public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/96182] New: GCC accepts constexpr function with no return-statement
@ 2020-07-13 11:52 haoxintu at gmail dot com
  2020-07-13 11:59 ` [Bug c++/96182] " jakub at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: haoxintu at gmail dot com @ 2020-07-13 11:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

            Bug ID: 96182
           Summary: GCC accepts constexpr function with no
                    return-statement
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: accepts-invalid
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: haoxintu at gmail dot com
  Target Milestone: ---

Hi,all.

This code, test.cc, is an invalid code I guess, but GCC accepts it.

$cat test.cc
constexpr int
foo()
{}

$g++ test.cc
test.cc: In function ‘constexpr int foo()’:
test.cc:3:2: warning: no return statement in function returning non-void
[-Wreturn-type]
    3 | {}
      |  ^

GCC only emits normal -Wreturn-type warning and then accepts it.

Weirdly, this code is rejected under -std=c++11.

$g++ -std=c++11 test.cc
test.cc: In function ‘constexpr int foo()’:
test.cc:3:2: error: body of ‘constexpr’ function ‘constexpr int foo()’ not a
return-statement
    3 | {}
      |  ^
test.cc:3:2: warning: no return statement in function returning non-void
[-type-Wreturn-type]

I think constexpr function is not a deprecated feature in c++14. I also test
this in Clang, it is rejected by both standards.

Every GCC versions from 5.1 to trunk behave the same.

Thanks,
Haoxin

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
@ 2020-07-13 11:59 ` jakub at gcc dot gnu.org
  2020-07-13 12:09 ` haoxintu at gmail dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-07-13 11:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The difference is that in C++11 the standard requires that the body of a
constexpr function is return expression, that is not the case of C++14 anymore.
And, you'd get an error if you tried constexpr int a = foo (); i.e. when it is
evaluated in constant expression, but when it is only evaluated e.g. in int b =
foo (); it is a problem only at runtime.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
  2020-07-13 11:59 ` [Bug c++/96182] " jakub at gcc dot gnu.org
@ 2020-07-13 12:09 ` haoxintu at gmail dot com
  2020-07-13 12:18 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: haoxintu at gmail dot com @ 2020-07-13 12:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

--- Comment #2 from Haoxin Tu <haoxintu at gmail dot com> ---
(In reply to Jakub Jelinek from comment #1)
> The difference is that in C++11 the standard requires that the body of a
> constexpr function is return expression, that is not the case of C++14
> anymore.
> And, you'd get an error if you tried constexpr int a = foo (); i.e. when it
> is evaluated in constant expression, but when it is only evaluated e.g. in
> int b = foo (); it is a problem only at runtime.

Thank you, Jakub.

At runtime this must be a error. But I guess should it be rejected at compile
time?

Maybe reject this in compile time will help users to fix this issue early, like
other mainstream compilers do. Just for a suggestion, please understand if
anything I stated is unsuitable.

Thanks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
  2020-07-13 11:59 ` [Bug c++/96182] " jakub at gcc dot gnu.org
  2020-07-13 12:09 ` haoxintu at gmail dot com
@ 2020-07-13 12:18 ` jakub at gcc dot gnu.org
  2020-07-13 12:21 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-07-13 12:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
E.g.
constexpr int foo (int x) { if (x == 5) return 3; } constexpr int a = foo (5);
is accepted just with warning by both compilers and I think that is right, it
is only an error if one does constexpr int b = foo (4); or similar.
But for some reason clang treats your case differently (when there are no
return statements at all), but only in constexpr functions.  Not sure how is it
backed up, unless the standard says that a constexpr function must have a
return statement or something similar, not sure if that is ok.  It is true that
in these cases all invocations of such function in constant expression contexts
will result in an error, but if you don't invoke them...

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
                   ` (2 preceding siblings ...)
  2020-07-13 12:18 ` jakub at gcc dot gnu.org
@ 2020-07-13 12:21 ` jakub at gcc dot gnu.org
  2020-07-13 12:28 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-07-13 12:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Or another possible wording would be that a constexpr function which is not a
valid constant expression for all possible parameter values is invalid.
I believe such wording is there for templates and instead of parameter values
all template arguments.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
                   ` (3 preceding siblings ...)
  2020-07-13 12:21 ` jakub at gcc dot gnu.org
@ 2020-07-13 12:28 ` redi at gcc dot gnu.org
  2020-07-13 12:36 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2020-07-13 12:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
           Keywords|accepts-invalid             |diagnostic
   Last reconfirmed|                            |2020-07-13
           Severity|normal                      |enhancement

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
[decl.constexpr] p6 in the C++ standard says:

"if no argument values exist such that an invocation of the function or
constructor could be an evaluated subexpression of a core constant expression
[...] the program is ill-formed, no diagnostic required."

So the foo() function is ill-formed, but implementations are not required to
diagnose it unless the function is actually evaluated.

So this is not accepts-invalid, but I'll confirm it as a request for a
diagnostic enhancement.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
                   ` (4 preceding siblings ...)
  2020-07-13 12:28 ` redi at gcc dot gnu.org
@ 2020-07-13 12:36 ` jakub at gcc dot gnu.org
  2020-07-31 21:08 ` cvs-commit at gcc dot gnu.org
  2021-08-28  0:03 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-07-13 12:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So we could do something like:
--- gcc/cp/decl.c.jj    2020-07-09 11:27:51.088908783 +0200
+++ gcc/cp/decl.c       2020-07-13 14:34:59.887259561 +0200
@@ -17164,7 +17164,9 @@ finish_function (bool inline_p)
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;

   /* Complain if there's just no return statement.  */
-  if (warn_return_type
+  if ((warn_return_type
+       || (cxx_dialect >= cxx14
+          && DECL_DECLARED_CONSTEXPR_P (fndecl)))
       && !VOID_TYPE_P (TREE_TYPE (fntype))
       && !dependent_type_p (TREE_TYPE (fntype))
       && !current_function_returns_value && !current_function_returns_null
@@ -17196,8 +17198,12 @@ finish_function (bool inline_p)
                                            global_dc->option_state))
            add_return_star_this_fixit (&richloc, fndecl);
        }
-      if (warning_at (&richloc, OPT_Wreturn_type,
-         "no return statement in function returning non-void"))
+      if (cxx_dialect >= cxx14 && DECL_DECLARED_CONSTEXPR_P (fndecl))
+       error_at (&richloc, "no return statement in %<constexpr%> function "
+                           "returning non-void");
+      else if (warning_at (&richloc, OPT_Wreturn_type,
+                          "no return statement in function returning "
+                          "non-void"))
        TREE_NO_WARNING (fndecl) = 1;
     }

and look for what breaks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
                   ` (5 preceding siblings ...)
  2020-07-13 12:36 ` jakub at gcc dot gnu.org
@ 2020-07-31 21:08 ` cvs-commit at gcc dot gnu.org
  2021-08-28  0:03 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-07-31 21:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:5f9669d9e23a1116e040c80e0f3d4f43639bda52

commit r11-2473-g5f9669d9e23a1116e040c80e0f3d4f43639bda52
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Jul 31 23:08:00 2020 +0200

    c++: Use error_at rather than warning_at for missing return in constexpr
functions [PR96182]

    For C++11 we already emit an error if a constexpr function doesn't contain
    a return statement, because in C++11 that is the only thing it needs to
    contain, but for C++14 we would normally issue a -Wreturn-type warning.

    As mentioned by Jonathan, such constexpr functions are invalid, no
    diagnostics required, because there doesn't exist any arguments for
    which it would result in valid constant expression.

    This raises it to an error in such cases.  The !LAMBDA_TYPE_P case
    is to avoid error on g++.dg/pr81194.C where the user didn't write
    constexpr anywhere and the operator() is compiler generated.

    2020-07-31  Jakub Jelinek  <jakub@redhat.com>

            PR c++/96182
            * decl.c (finish_function): In constexpr functions use for C++14
and
            later error instead of warning if no return statement is present
and
            diagnose it regardless of warn_return_type.  Move the
warn_return_type
            diagnostics earlier in the function.

            * g++.dg/cpp1y/constexpr-96182.C: New test.
            * g++.dg/other/error35.C (S<T>::g()): Add return statement.
            * g++.dg/cpp1y/pr63996.C (foo): Likewise.
            * g++.dg/cpp1y/constexpr-return2.C (f): Likewise.
            * g++.dg/cpp1y/var-templ44.C (make_array): Add throw 1.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/96182] GCC accepts constexpr function with no return-statement
  2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
                   ` (6 preceding siblings ...)
  2020-07-31 21:08 ` cvs-commit at gcc dot gnu.org
@ 2021-08-28  0:03 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-28  0:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96182

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |55004
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED
   Target Milestone|---                         |11.0

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Fixed so closing.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55004
[Bug 55004] [meta-bug] constexpr issues

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-08-28  0:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-13 11:52 [Bug c++/96182] New: GCC accepts constexpr function with no return-statement haoxintu at gmail dot com
2020-07-13 11:59 ` [Bug c++/96182] " jakub at gcc dot gnu.org
2020-07-13 12:09 ` haoxintu at gmail dot com
2020-07-13 12:18 ` jakub at gcc dot gnu.org
2020-07-13 12:21 ` jakub at gcc dot gnu.org
2020-07-13 12:28 ` redi at gcc dot gnu.org
2020-07-13 12:36 ` jakub at gcc dot gnu.org
2020-07-31 21:08 ` cvs-commit at gcc dot gnu.org
2021-08-28  0:03 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).