Summary: | [4.2 Regression] Incorrect "no return statement" warning with __attribute__ ((noreturn)) and __FUNCTION__ | ||
---|---|---|---|
Product: | gcc | Reporter: | Geoffrey Irving <irving> |
Component: | c++ | Assignee: | Jakub Jelinek <jakub> |
Status: | RESOLVED FIXED | ||
Severity: | minor | CC: | fang, gcc-bugs, spark |
Priority: | P2 | Keywords: | diagnostic |
Version: | 4.1.1 | ||
Target Milestone: | 4.3.0 | ||
Host: | x86_64-redhat-linux | Target: | x86_64-redhat-linux |
Build: | x86_64-redhat-linux | Known to work: | 3.3.3 4.3.0 |
Known to fail: | 3.4.0 4.0.0 4.1.0 4.2.0 4.2.5 | Last reconfirmed: | 2007-11-18 22:21:37 |
Description
Geoffrey Irving
2007-02-27 22:18:52 UTC
*** Bug 30993 has been marked as a duplicate of this bug. *** Confirmed, a regression from 3.3.3. I made sure in 3.3.3, we would warn about the function if we removed the attribute noreturn so I know the warning works for that case. This is somewhat complicated. The extra type cast causes different code paths to be taken. In particular, in finish_call_expr() in cp/semantics.c: if (processing_template_decl) { if (type_dependent_expression_p (fn) || any_type_dependent_arguments_p (args)) { result = build_nt_call_list (fn, args); KOENIG_LOOKUP_P (result) = koenig_p; return result; } if (!BASELINK_P (fn) && TREE_CODE (fn) != PSEUDO_DTOR_EXPR && TREE_TYPE (fn) != unknown_type_node) fn = build_non_dependent_expr (fn); args = build_non_dependent_args (orig_args); With the type cast, build_over_call() is called eventually which checks TREE_THIS_VOLATILE() for the callee function decl and mark the current function (i.e. caller A::g) as returns_abnormally. The lack of the type cast triggers any_type_dependent_arguments_p(args) above, leading to build_nt_call_list() which doesn't do this marking of the returns_abnormally. Now, not being familiar with the c++ frontend, I'm not sure where exactly we should do the checking of TREE_THIS_VOLATILE() for the callee decl. The following patch seems to fix the problem (though I can't even tell whether this is the right approach): diff -r 15a559a8fcf0 gcc/cp/semantics.c --- a/gcc/cp/semantics.c Mon Mar 12 15:38:22 2007 -0700 +++ b/gcc/cp/semantics.c Tue Mar 13 15:48:45 2007 -0700 @@ -1816,6 +1816,10 @@ finish_call_expr (tree fn, tree args, bo || any_type_dependent_arguments_p (args)) { result = build_nt_call_list (fn, args); + + if (fn && TREE_THIS_VOLATILE (fn) && cfun) + current_function_returns_abnormally = 1; + KOENIG_LOOKUP_P (result) = koenig_p; return result; } IMNSHO this is not a regression. void f (const char *) #ifdef NORET __attribute__ ((noreturn)) #endif ; template <class T> struct A { int g () { #ifdef TEST1 f (__FUNCTION__); #elif defined TEST2 f ((const char*) __FUNCTION__); #else f ((const char *) 0); #endif } }; for k in gcc-2.96-rh gcc-3.2 gcc-3.3 gcc-3.4 gcc-4.1 gcc-4.2 gcc-4.3; do for i in " -DNORET" ""; do \ for j in -DTEST1 -DTEST3 -DTEST3; do \ /usr/src/$k/obj/gcc/cc1plus $i $j pr30988.C -O3 -Wall -quiet 2>&1 \ | sed -n "/warning:/s/^/$k$i $j /p"; done; done; done gcc-3.2 -DNORET -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.2 -DNORET -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.2 -DNORET -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.2 -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.2 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.2 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.4 -DNORET -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.4 -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.4 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-3.4 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.1 -DNORET -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.1 -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.1 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.1 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.2 -DNORET -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.2 -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.2 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.2 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.3 -DNORET -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.3 -DTEST1 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.3 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void gcc-4.3 -DTEST3 pr30988.C:18: warning: no return statement in function returning non-void So, gcc-2.96-RH and 3.3 wouldn't warn ever in templates, even for cases where it should warn, e.g. when the argument is not type dependent and neither the called function has noreturn attribute. Oops, sorry for the typo (twice -DTEST3, never -DTEST2). But with -DTEST2 the output is always identical to -DTEST3 with all compilers. Subject: Bug 30988 Author: jakub Date: Sun Nov 18 22:20:54 2007 New Revision: 130280 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130280 Log: PR c++/30988 semantics.c (finish_call_expr): Set current_function_returns_abnormally if fn is noreturn FUNCTION_DECL or OVERLOAD with all noreturn functions. * g++.dg/warn/noreturn-4.C: New test. * g++.dg/warn/noreturn-5.C: New test. * g++.dg/warn/noreturn-6.C: New test. * g++.dg/warn/noreturn-7.C: New test. Added: trunk/gcc/testsuite/g++.dg/warn/noreturn-4.C trunk/gcc/testsuite/g++.dg/warn/noreturn-5.C trunk/gcc/testsuite/g++.dg/warn/noreturn-6.C trunk/gcc/testsuite/g++.dg/warn/noreturn-7.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/semantics.c trunk/gcc/testsuite/ChangeLog Fixed on the trunk. Closing 4.1 branch. Closing 4.2 branch, fixed in 4.3. (In reply to comment #9) > Closing 4.2 branch, fixed in 4.3. Thanks! |