From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id aR/pKkvvBmrO7DwAWB0awg (envelope-from ) for ; Fri, 15 May 2026 06:02:51 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QGMq0VfX; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id A629C1E0B1; Fri, 15 May 2026 06:02:51 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id DAA391E093 for ; Fri, 15 May 2026 06:02:49 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7A0B14BBC0D6 for ; Fri, 15 May 2026 10:02:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7A0B14BBC0D6 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QGMq0VfX Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 7A7F251A4314 for ; Fri, 15 May 2026 10:01:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7A7F251A4314 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7A7F251A4314 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778839263; cv=none; b=VZO120NDk2wBiIjXVC/ASX0eT8Xt8AOz5LpvkNELF6CT5IbyeQnEtbqszQtP8noVgHTOgMWapGgkvfcysrYGSGLPYSd9bNTn+oF9tbOxMvho7BZUqzocKPs1+oHmXDAq8M0xSkl8TfzEEwSydUPoUbyUvJf0VG/xdxIicpbq/Iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778839263; c=relaxed/simple; bh=BN6S8TWY0ekcFUXEnuZn64rFolvj0/+eMljLxP9BQZc=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=UukXNAbCGYMso0+FNvbDwEvLUFQiX85w4s9b3//sI6jEveTPaOZNC+gfjCXYdMtk06aVYqIBfUDo1I5ZxRbwB5GdXv2adr3TQuLNkU1SJIk8Naje63UxkxJrlmr/brnuxXQc9VaVk7JQwXUynHsHwYMQz3nPyHq9yBTs4OFv4sE= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QGMq0VfX DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7A7F251A4314 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778839263; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s5eaEE0SYrEAyo4BS/kYGyrTaKf7heaT42SCuh+YC9o=; b=QGMq0VfXpMFvMsaSctjbcP6RbXWUNDMVE3/Dr+023+FGaqtooQ8uqJ60VLeK2nnyco+T1O ktzCmAsBtwD8rMay324nAcNOIDXzpVqIbMojci7hhqGQnbM0eQ8Z5wPCii9Dwoxw4s7iU5 VZBU9d1pDVer86UpgnwH4sMgIZYBa5s= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-658-ljQnIMcPMLSbb_8T1BZ5xw-1; Fri, 15 May 2026 06:01:01 -0400 X-MC-Unique: ljQnIMcPMLSbb_8T1BZ5xw-1 X-Mimecast-MFC-AGG-ID: ljQnIMcPMLSbb_8T1BZ5xw_1778839260 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-44a122a5128so6842182f8f.0 for ; Fri, 15 May 2026 03:01:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778839260; x=1779444060; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=s5eaEE0SYrEAyo4BS/kYGyrTaKf7heaT42SCuh+YC9o=; b=qUk/tmRZHOtO7nThpvTyfwQI1MLMgHMsZaERedIWHf2e1/Wg5IKPV/xwdItGpbUfYW 3kolSJ6Qp+BPkUYMdXlJxeJULVADWBX7O3mh8AWsd3rRJZVmfXBV6qSzOrabLu1U347F TUXSMBYri06sEJtrY2F6dADcwuGBlQ/IQ9GPz5cAZCdZa6p4uluW8ZtkCZyja2RWd4F3 ro8HsXA72jZtZXLTOpTo5RW2SoQ+CkwGiXyGeFF+i66x/0/xX2AOho1h6Kt4HuDeq05g Vx1DgRfb+lWUnHbeJh+ed5q3CxgIMsrHZhgNzV8vw3H/TQ8qVDDRYMIpBYaDItcKzHGY Tk7w== X-Gm-Message-State: AOJu0Yze/ZNiLJkF5TyGSCuTbKVKwrQAxRLJ+PcS2F0Hhfu2eRf8rwkT QX6nzLtJl41oyKWnVoEIt0DsV/u/LyCTVd0/XPMa8VuG2R8pIkIhE4jZ9d8UPIAMjPHRP9KsCcj FflQyy+kApSgBqTaM0VaCz8Ws9pdoaTz4jAhKiFX0RtOmS63yYn5EM5kekpCD91i4BZWLJJlQXt ZgYJvmI9o32vtkzXK1bkJLxfhoEhZ0ska2UwlPNXdkugCvmLE= X-Gm-Gg: Acq92OHr3ofKyZMAdqFxL7XLtYRtTX6l0Ji9nnbqEqOr1sIleUXU8IQBbQupE9mrIZu dT0GenrrPDJaf+N6Qip18qxMdhr/18lXrEORceorWtqzULtpqqbp4H9kpBn9bb44/PYXv8j7+m7 LncjeeXEFJTTUyVyX6PWBOmoRJKsP9p8TrZ9zh9zjkoevJaLdLUKBiz1y1PoW6PZQE5TKCRngyt EJfGQO+XO3vWnmE8Nvh64HRwvlJMyM6EMYSaLnZgt4dfSsWxxPBeEAe6dEgCSjd6oCAe4Ba5WJd CWLkwRa60yoeNJsLWqDENcDcVMCb8P9Crj7hT4/EUkILWLCtumDJUswJ8D+amtpSDEEjw0LKqZP 4C0t/aRapvw1gFzqo X-Received: by 2002:a05:6000:2081:b0:452:6aa0:1d11 with SMTP id ffacd0b85a97d-45e5c59a132mr4436978f8f.19.1778839259652; Fri, 15 May 2026 03:00:59 -0700 (PDT) X-Received: by 2002:a05:6000:2081:b0:452:6aa0:1d11 with SMTP id ffacd0b85a97d-45e5c59a132mr4436892f8f.19.1778839258915; Fri, 15 May 2026 03:00:58 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45d9adc2209sm12055153f8f.0.2026.05.15.03.00.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 May 2026 03:00:57 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 3/3] gdb/testsuite: add a test to check for Python traits static_assert Date: Fri, 15 May 2026 11:00:48 +0100 Message-Id: <93b625c0ab2f23cafa636d42e503361b70ee6edf.1778839043.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: AkepSIAisbjzyDjXBqHK8Kzg8vPAuXarDoX9OlY9EpY_1778839260 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org The previous two commits added a new type trait which can be used within a static_assert to check the properties of a struct used by GDB to implement Python objects. The previous commit fixed a bug in GDB which this trait check exposed. This commit adds a new test gdb.gdb/python-traits-check.exp which checks that every struct in the Python/ directory that inherits from PyObject, has a suitable static_assert in place. Adding this test should mean that if someone adds a new Python object type to GDB, and they forget to add the static_assert, then this test should give a failure, which should remind them to add the required static_assert. The static_assert will then check that their new struct is compliant. --- gdb/testsuite/gdb.gdb/python-traits-check.exp | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 gdb/testsuite/gdb.gdb/python-traits-check.exp diff --git a/gdb/testsuite/gdb.gdb/python-traits-check.exp b/gdb/testsuite/gdb.gdb/python-traits-check.exp new file mode 100644 index 00000000000..46cb1cabbb0 --- /dev/null +++ b/gdb/testsuite/gdb.gdb/python-traits-check.exp @@ -0,0 +1,156 @@ +# Copyright 2026 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that every struct inheriting from PyObject in the gdb/python/ +# directory has a corresponding static_assert for +# gdb::is_python_allocatable_v immediately after the struct definition. +# The expected format is: +# +# struct some_new_type : public PyObject +# { +# ... fields go here ... +# }; +# +# static_assert (gdb::is_python_allocatable_v); +# +# It is OK to add comments between the struct and the static_assert if +# needed, but nothing else, the static_assert must be the next non-empty, +# non-comment line. +# +# If the new type has no fields then this can be written like: +# +# struct some_empty_type : public PyObject +# {}; +# +# static_assert (gdb::is_python_allocatable_v); +# +# We do have a few of these in GDB currently. We require that the +# static_assert still be present because (a) it has zero run-time cost, +# and (b) it catches issues if fields are added in the future. + +set python_dir "$srcdir/$subdir/../../python" + +# Gather all .c and .h files in the python directory. +set files [lsort [concat \ + [glob -nocomplain -directory $python_dir *.c] \ + [glob -nocomplain -directory $python_dir *.h]]] + +gdb_assert { [llength $files] > 0 } "found python source files" + +# Check a single file for PyObject-derived structs and matching +# static_asserts. +# +# Opens FILENAME, reads it line by line looking for struct definitions of +# the form "struct NAME : public PyObject". For each one found, scans +# forward past the struct body, then checks that a matching static_assert +# line follows, allowing only blank lines and GDB-style comments to +# intervene. + +proc check_file { filename } { + set fd [open $filename r] + set lines [split [read $fd] "\n"] + close $fd + + set num_lines [llength $lines] + set short_name [file tail $filename] + + for { set i 0 } { $i < $num_lines } { incr i } { + set line [lindex $lines $i] + + # Look for struct definitions inheriting from PyObject. These + # start in column 0. + if { ![regexp {^struct (\w+)\s*:\s*public PyObject} \ + $line whole struct_name] } { + continue + } + + set testname "$short_name: $struct_name: static assert check" + + # Found a struct. Now scan forward for the closing brace and + # semicolon. Within the struct body, lines are either blank or + # start with whitespace. The closing line starts in column 0. For + # empty structs the open and close brace may appear together on a + # single line. + set found_close false + for { incr i } { $i < $num_lines } { incr i } { + set line [lindex $lines $i] + if { [regexp "^(?:\\{\\s*)?\\};" $line] } { + set found_close true + break + } + } + + if { !$found_close } { + fail "$testname (no closing brace found)" + continue + } + + # Now scan forward from the line after the struct close, skipping + # empty lines and GDB-style /* ... */ comments. The next non-blank, + # non-comment line should be the static_assert. + set in_comment false + set found_assert false + set found_other false + for { incr i } { $i < $num_lines } { incr i } { + set line [lindex $lines $i] + + if { $in_comment } { + # Inside a multi-line comment, look for the closing "*/". + if { [regexp {\*/} $line] } { + set in_comment false + } + continue + } + + # Skip blank lines. + if { [regexp {^\s*$} $line] } { + continue + } + + # Check for the start of a comment. + if { [regexp {^\s*/\*} $line] } { + # If the comment also ends on this line then we don't need + # to enter IN_COMMENT mode, we can just ignore this line. + if { ![regexp {\*/} $line] } { + set in_comment true + } + continue + } + + # This is a non-blank, non-comment line. Check if it is the + # expected static_assert. + set expected \ + "static_assert (gdb::is_python_allocatable_v<$struct_name>);" + if { $line eq $expected } { + set found_assert true + } else { + set found_other true + } + break + } + + if { $found_assert } { + pass $testname + } elseif { $found_other } { + fail "$testname (missing static_assert)" + } else { + fail "$testname (reached end of file)" + } + } +} + +foreach file $files { + check_file $file +} -- 2.25.4