Hi!

This is something Jonathan has asked for recently.  E.g. in the recent
libstdc++ r16-6177 random.tcc changes, there was
         if constexpr (__d <= 32)                                               
                                                                                
                     
           return __generate_canonical_any<_RealT, uint64_t, __d>(__urng);      
                                                                                
                     
         else                                                                   
                                                                                
                     
           {                                                                    
                                                                                
                     
#if defined(__SIZEOF_INT128__)                                                  
                                                                                
                     
             static_assert(__d <= 64,                                           
                                                                                
                     
               "irregular RNG with float precision >64 is not supported");      
                                                                                
                     
             return __generate_canonical_any<                                   
                                                                                
                     
               _RealT, unsigned __int128, __d>(__urng);                         
                                                                                
                     
#else                                                                           
                                                                                
                     
             static_assert(false, "irregular RNG with float precision"          
                                                                                
                     
                " >32 requires __int128 support");                              
                                                                                
                     
#endif                                                                          
                                                                                
                     
           }                                                                    
                                                                                
                     
and when we hit there the static_assert, we don't get just an error about
that, but also a -Wreturn-type warning in the same function because that
path falls through to the end of function without returning a value.
But a function with a failed static_assert is erroneous and will never
fall through to the end.  We could treat failed static_assert in functions
as __builtin_unreachable (), but I think it doesn't matter where exactly
in a function static_assert(false); appears, so this patch just suppresses
-Wreturn-type warning in that function instead.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-12-19  Jakub Jelinek  <[email protected]>

        * semantics.cc (finish_static_assert): Suppress -Wreturn-type warnings
        in functions with failed assertions.

        * g++.dg/cpp1z/static_assert1.C: New test.

--- gcc/cp/semantics.cc.jj      2025-12-13 09:54:13.142393769 +0100
+++ gcc/cp/semantics.cc 2025-12-18 17:59:15.961112063 +0100
@@ -12927,6 +12927,16 @@ finish_static_assert (tree condition, tr
            error_at (cloc, "static assertion failed: %.*s", len, msg);
 
          diagnose_failing_condition (bad, cloc, show_expr_p);
+
+         /* Suppress -Wreturn-type for functions with failed static_asserts.
+            Otherwise templates like:
+            if constexpr (whatever)
+              return something (args);
+            else
+              static_assert (false, "explanation");
+            get a useless extra -Wreturn-type warning.  */
+         if (current_function_decl)
+           suppress_warning (current_function_decl, OPT_Wreturn_type);
        }
       else if (condition && condition != error_mark_node)
        {
--- gcc/testsuite/g++.dg/cpp1z/static_assert1.C.jj      2025-12-18 
18:03:17.867763452 +0100
+++ gcc/testsuite/g++.dg/cpp1z/static_assert1.C 2025-12-18 18:03:00.642073110 
+0100
@@ -0,0 +1,16 @@
+// Make sure we don't emit -Wreturn-type in functions with failed 
static_asserts.
+// { dg-do compile { target c++17 } }
+
+template <int N>
+int
+foo ()
+{
+  if constexpr (N <= 42)
+    return N;
+  else
+    static_assert (false, "too high N");       // { dg-error "too high N" }
+}                                              // { dg-bogus "no return 
statement in function returning non-void" }
+
+int a = foo <0> ();
+int b = foo <42> ();
+int c = foo <100> ();

        Jakub

Reply via email to