On 9/9/26 12:08 PM, Marek Polacek wrote:
On Wed, Sep 09, 2026 at 05:22:24PM +0200, Jakub Jelinek wrote:
On Wed, Sep 09, 2026 at 10:00:48AM -0400, Jason Merrill wrote:
On 9/9/26 6:08 AM, Jakub Jelinek wrote:
On Wed, Sep 09, 2026 at 12:06:14PM +0200, Tomasz Kaminski wrote:
--- a/gcc/cp/cp-gimplify.cc 2026-09-09 17:03:29.375511108 +0200
+++ b/gcc/cp/cp-gimplify.cc 2026-09-09 17:08:09.020290280 +0200
@@ -1040,6 +1040,7 @@ cp_gimplify_expr (tree *expr_p, gimple_s
0));
break;
case CP_BUILT_IN_CONSTEXPR_DIAG:
+ case CP_BUILT_IN_START_LIFETIME:
*expr_p = void_node;
Is it safe to drop this when the argument has side-effects?
break;
default:
--- a/gcc/cp/semantics.cc 2026-09-09 17:03:29.386510966 +0200
+++ b/gcc/cp/semantics.cc 2026-09-09 17:08:09.021167493 +0200
@@ -3300,6 +3300,82 @@ perform_koenig_lookup (cp_expr fn_expr,
return cp_expr (fn, loc);
}
+/* Analyze call to a front-end builtin FN with arguments *ARGS. Return true
+ if the call is correct, false if erroneous. */
+
+static bool
+check_frontend_builtin (tree fn, vec<tree, va_gc> **args,
+ tsubst_flags_t complain)
+{
+ tree arg, ptype, type;
+ switch (DECL_UNCHECKED_FUNCTION_CODE (fn))
+ {
+ case CP_BUILT_IN_IS_WITHIN_LIFETIME:
+ /* Unless users call the builtin directly, the following 2 checks
+ should be ensured from std::is_within_lifetime template. */
+ if (vec_safe_length (*args) != 1)
+ {
+ if (complain & tf_error)
+ error ("%qs needs a single argument",
+ "__builtin_is_within_lifetime");
+ return false;
+ }
+ arg = (**args)[0];
+ if (error_operand_p (arg))
+ return false;
+ ptype = TREE_TYPE (arg);
+ if (!POINTER_TYPE_P (ptype))
+ {
+ if (complain & tf_error)
+ error ("%qs argument type %qT is not pointer type",
+ "__builtin_is_within_lifetime", ptype);
+ return false;
+ }
+ return true;
+ case CP_BUILT_IN_START_LIFETIME:
This:
+ /* Unless users call the builtin directly, the following 2 checks
+ should be ensured from std::start_lifetime template. */
+ if (vec_safe_length (*args) != 1)
+ {
+ if (complain & tf_error)
+ error ("%qs needs a single argument", "__builtin_start_lifetime");
+ return false;
+ }
+ arg = (**args)[0];
+ if (error_operand_p (arg))
+ return false;
+ ptype = TREE_TYPE (arg);
+ if (!POINTER_TYPE_P (ptype))
+ {
+ if (complain & tf_error)
+ error ("%qs argument type %qT is not pointer type",
+ "__builtin_start_lifetime", ptype);
+ return false;
+ }
seems to duplicate the previous case almost verbatim.
Indeed, and perhaps we could use DECL_NAME (fn) instead of extra string
literals in the diagnostics?
+ type = TREE_TYPE (ptype);
+ if (!complete_type_or_else (type, NULL_TREE))
This emits a diagnostic unconditionally, should it be
complete_type_or_maybe_complain? Elsewhere this function
checks complain first.
Good point.
Jason