]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: improved return expression location
authorJason Merrill <jason@redhat.com>
Fri, 19 Nov 2021 22:01:10 +0000 (17:01 -0500)
committerJason Merrill <jason@redhat.com>
Mon, 22 Nov 2021 22:42:53 +0000 (17:42 -0500)
Stripping the location wrapper from retval meant we didn't have the
necessary location information for any conversion diagnostics.  We only need
the stripping for the named return value optimization, let's use the
unstripped expression for everything else.

gcc/cp/ChangeLog:

* typeck.c (check_return_expr): Only strip location wrapper during
NRV handling.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/pr65327.C: Adjust location.
* g++.dg/cpp23/constexpr-nonlit4.C: Likewise.
* g++.dg/cpp23/constexpr-nonlit5.C: Likewise.
* g++.dg/cpp2a/constexpr-init1.C: Likewise.

gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp0x/pr65327.C
gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C

index 58919aaf13e963f1fa875574fbfc6eb6b6bfdb07..63a0eaef2da68c51ed66e8949b9b2f01fda7b832 100644 (file)
@@ -10545,19 +10545,20 @@ check_return_expr (tree retval, bool *no_warning)
      this restriction, anyway.  (jason 2000-11-19)
 
      See finish_function and finalize_nrv for the rest of this optimization.  */
+  tree bare_retval = NULL_TREE;
   if (retval)
     {
       retval = maybe_undo_parenthesized_ref (retval);
-      STRIP_ANY_LOCATION_WRAPPER (retval);
+      bare_retval = tree_strip_any_location_wrapper (retval);
     }
 
-  bool named_return_value_okay_p = can_do_nrvo_p (retval, functype);
+  bool named_return_value_okay_p = can_do_nrvo_p (bare_retval, functype);
   if (fn_returns_value_p && flag_elide_constructors)
     {
       if (named_return_value_okay_p
           && (current_function_return_value == NULL_TREE
-              || current_function_return_value == retval))
-       current_function_return_value = retval;
+             || current_function_return_value == bare_retval))
+       current_function_return_value = bare_retval;
       else
        current_function_return_value = error_mark_node;
     }
@@ -10571,7 +10572,7 @@ check_return_expr (tree retval, bool *no_warning)
     maybe_warn_pessimizing_move (retval, functype);
 
   /* Do any required conversions.  */
-  if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
+  if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
     /* No conversions are required.  */
     ;
   else
index 6e888ebff2ce0fef44de5dbc0decfef2582d6b60..e8149953ffd4402158d5b18674b5949bd8bc4c09 100644 (file)
@@ -14,5 +14,5 @@ foo ()
 constexpr volatile int // { dg-warning "deprecated" "" { target c++2a } }
 bar ()
 {
-  return i;
-} // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+  return i;  // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+}
index e4ed2e36c3057ebdc262eb513ee116e6559fc5ee..bdc97a9bc79213b0776ffa8262ed0d81c69a605f 100644 (file)
@@ -34,7 +34,7 @@ baz (int x)
     {
       static const int v = qux ();     // { dg-message "'v' was not initialized with a constant expression" }
     case 12:
-      return v;
+      return v;        // { dg-error "the value of 'v' is not usable in a constant expression" }
     }
   return 0;
 }
@@ -46,12 +46,12 @@ corge (int x)
     {
       const thread_local int v = qux ();       // { dg-message "'v' was not initialized with a constant expression" }
     case 12:
-      return v;
+      return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
     }
   return 0;
 }
 
 constexpr int a = foo (12);
 constexpr int b = bar (12);
-constexpr int c = baz (12);            // { dg-error "the value of 'v' is not usable in a constant expression" }
-constexpr int d = corge (12);          // { dg-error "the value of 'v' is not usable in a constant expression" }
+constexpr int c = baz (12);
+constexpr int d = corge (12);
index 838f282c1f9421dd090e0ad7d10680d847f2daeb..86d5dba77a39e0ec067dfbdb3ff1473f042a9c85 100644 (file)
@@ -34,7 +34,7 @@ baz (int x)
     {
       static int v = 6;        // { dg-message "int v' is not const" }
     case 12:
-      return v;
+      return v;        // { dg-error "the value of 'v' is not usable in a constant expression" }
     }
   return 0;
 }
@@ -46,12 +46,12 @@ corge (int x)
     {
       thread_local int v = 6;  // { dg-message "int v' is not const" }
     case 12:
-      return v;
+      return v;        // { dg-error "the value of 'v' is not usable in a constant expression" }
     }
   return 0;
 }
 
 constexpr int a = foo (12);
 constexpr int b = bar (12);
-constexpr int c = baz (12);            // { dg-error "the value of 'v' is not usable in a constant expression" }
-constexpr int d = corge (12);          // { dg-error "the value of 'v' is not usable in a constant expression" }
+constexpr int c = baz (12);
+constexpr int d = corge (12);
index 75984a2fdcb7335a13940a969a3e24cf4e68ab1c..e56ecfed48adb93e260e8323235949935eb6c82a 100644 (file)
@@ -73,11 +73,11 @@ fn7 (bool b)
   int a; // { dg-message ".int a. is not const" }
   if (b)
     a = 42;
-  return a;
+  return a;                   // { dg-error "the value of .a. is not usable" }
 }
 
 static_assert (fn7 (true) == 42);
-static_assert (fn7 (false) == 42); // { dg-error "non-constant condition|the value of .a. is not usable" }
+static_assert (fn7 (false) == 42); // { dg-error "non-constant condition" }
 // { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-1 }
 
 constexpr int