]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/typeck.c
c++: Fix up taking address of an immediate function diagnostics [PR102753]
[thirdparty/gcc.git] / gcc / cp / typeck.c
index 872e944dc2e3ce601b004fa963a8e27426fba857..5ed9a5ab9ee92f5a4c142f3be49bde233a3c2048 100644 (file)
@@ -6497,7 +6497,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
       exp = cp_build_addr_expr_strict (xarg, complain);
 
       if (TREE_CODE (exp) == PTRMEM_CST)
-       exp = maybe_wrap_with_location (exp, loc);
+       PTRMEM_CST_LOCATION (exp) = loc;
       else
        protected_set_expr_location (exp, loc);
     }
@@ -6780,16 +6780,6 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
            return error_mark_node;
          }
 
-       if (TREE_CODE (t) == FUNCTION_DECL
-           && DECL_IMMEDIATE_FUNCTION_P (t)
-           && !in_immediate_context ())
-         {
-           if (complain & tf_error)
-             error_at (loc, "taking address of an immediate function %qD",
-                       t);
-           return error_mark_node;
-         }
-
        type = build_ptrmem_type (context_for_name_lookup (t),
                                  TREE_TYPE (t));
        t = make_ptrmem_cst (type, t);
@@ -6815,15 +6805,6 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
     {
       tree stripped_arg = tree_strip_any_location_wrapper (arg);
-      if (TREE_CODE (stripped_arg) == FUNCTION_DECL
-         && DECL_IMMEDIATE_FUNCTION_P (stripped_arg)
-         && !in_immediate_context ())
-       {
-         if (complain & tf_error)
-           error_at (loc, "taking address of an immediate function %qD",
-                     stripped_arg);
-         return error_mark_node;
-       }
       if (TREE_CODE (stripped_arg) == FUNCTION_DECL
          && !mark_used (stripped_arg, complain) && !(complain & tf_error))
        return error_mark_node;
@@ -6865,6 +6846,13 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
                              complain);
     }
 
+  /* For addresses of immediate functions ensure we have EXPR_LOCATION
+     set for possible later diagnostics.  */
+  if (TREE_CODE (val) == ADDR_EXPR
+      && TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL
+      && DECL_IMMEDIATE_FUNCTION_P (TREE_OPERAND (val, 0)))
+    SET_EXPR_LOCATION (val, input_location);
+
   return val;
 }
 
@@ -9571,8 +9559,12 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
                                 /*c_cast_p=*/0, tf_warning_or_error);
 
   if (!DECL_VIRTUAL_P (fn))
-    *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type),
-                   build_addr_func (fn, tf_warning_or_error));
+    {
+      tree t = build_addr_func (fn, tf_warning_or_error);
+      if (TREE_CODE (t) == ADDR_EXPR)
+       SET_EXPR_LOCATION (t, PTRMEM_CST_LOCATION (cst));
+      *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), t);
+    }
   else
     {
       /* If we're dealing with a virtual function, we have to adjust 'this'
@@ -9665,7 +9657,7 @@ convert_for_assignment (tree type, tree rhs,
   tree rhstype;
   enum tree_code coder;
 
-  location_t rhs_loc = EXPR_LOC_OR_LOC (rhs, input_location);
+  location_t rhs_loc = cp_expr_loc_or_input_loc (rhs);
   bool has_loc = EXPR_LOCATION (rhs) != UNKNOWN_LOCATION;
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue,
      but preserve location wrappers.  */