From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 090D938582BD for ; Wed, 7 Jun 2023 22:02:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 090D938582BD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1686175373; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ueayBVjXvgqIipM4WU9ULWCcrZrUaACuo/h9O0Sot14=; b=VcTDGgnFrZDqUJTrn1zBi81mufEq45Hwsh5RrJDRmhEnFtu2O8xDMnax9dKmvv6JXyP43W Hei+vDwoUv7xYreHV16zt9w7xSpf2AcRkHvHcpAOMB6yTHWD1M/ONIt6ldvjMFhPidXWmA Gr6XLeUeDHEdLel7ie3VbS7BQke1knk= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-539-mgc74mFNOu-VqOqXV3jWfQ-1; Wed, 07 Jun 2023 18:02:51 -0400 X-MC-Unique: mgc74mFNOu-VqOqXV3jWfQ-1 Received: by mail-qk1-f199.google.com with SMTP id af79cd13be357-75d4d5eda29so109337385a.1 for ; Wed, 07 Jun 2023 15:02:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686175370; x=1688767370; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:to:from:subject:message-id:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ueayBVjXvgqIipM4WU9ULWCcrZrUaACuo/h9O0Sot14=; b=bq890pxPzMy1ogwBbai4fTntlI1SplSYJLcdf4RgDh9ZdF3i9XInMxUFvtjl0P2Eaz OuyJsJqSfBp5ZKMe5U8DO024TJJSmjpPMftAdBHOx0xIB93d1DkvJ5QG1i4bj0ogwwH6 bzeKV42/amIYUBJmQK6l07O9gfIQn4dAxyTCpQIxxUqXUhWGJgeG/GAAFhtV+383dATP 2Go2ztGK7sli9b3n9rWnAaLWNLQ1Yq4b2mDl7b1wnQvAp5l6EHfkgR34Isayh0qzz4uC azvxwDV0rH9qgPdiuqTwWa2+81AQjxrqJNIO39evI/hSfpI4qhzAK6qEHGK5/Y0/1a5G pe8g== X-Gm-Message-State: AC+VfDwnRH8Fh8yayIEwzmrWzROfPj6vbDoIHRkLKKC30yupLrqNYQEe jWR835VHY4GvanH/NqxbYgVuVU0f7Vaux5n60zVxqblEez8bY+GwffceGwsQtbicbaaBFfGsd7U aF3sWA4I= X-Received: by 2002:a05:620a:2192:b0:75b:23a1:d844 with SMTP id g18-20020a05620a219200b0075b23a1d844mr569405qka.6.1686175370496; Wed, 07 Jun 2023 15:02:50 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5xI+xmWsmC0IBH617vzRRdmE5Z21LhagK4DyjNi1CZlQeyHHqTHNny9/LmlUXcD1IHJdDwVA== X-Received: by 2002:a05:620a:2192:b0:75b:23a1:d844 with SMTP id g18-20020a05620a219200b0075b23a1d844mr569375qka.6.1686175370165; Wed, 07 Jun 2023 15:02:50 -0700 (PDT) Received: from t14s.localdomain (c-76-28-97-5.hsd1.ma.comcast.net. [76.28.97.5]) by smtp.gmail.com with ESMTPSA id g1-20020a05620a108100b0075cc5e34e48sm171013qkk.131.2023.06.07.15.02.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jun 2023 15:02:49 -0700 (PDT) Message-ID: <679a02f05578ff416b326c84e91dc2545e449dfe.camel@redhat.com> Subject: Re: An overview of the analyzer support of the operator new From: David Malcolm To: Benjamin Priour , gcc@gcc.gnu.org Date: Wed, 07 Jun 2023 18:02:48 -0400 In-Reply-To: References: User-Agent: Evolution 3.44.4 (3.44.4-2.fc36) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-5.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Wed, 2023-06-07 at 19:19 +0200, Benjamin Priour wrote: > Hi, >=20 > I've been mapping where the analyzer is lacking support of the > operator new > different variants. > I've written a bunch of test cases already to demonstrate it, you can > find > them below. > They are not yet formatted for a patch submission, and as some of > them may > require new warnings, I didn't use dg-* directives either. You can always mark the dg-directives with "xfail" and a comment if the warning isn't implemented yet. > You will notice I included true positives and negatives as well, as I > think > they might spur ideas on some edge cases that may fail. > All that to say I would greatly appreciate your comments if any test > is > wrong, or if you have pointers on additional test cases. Looks great. Note that the results might be affected by exceptions; do any results change for -fexceptions versus -fno-exceptions? > You can also find a godbolt here. >=20 > The most annoying one is the recurrent noisy false positive > -Wanalyzer-possible-null-argument on usage of a new expression. > Although a placement new on a static buffer too short is flagged by > the > middle-end, the analyzer stay quiet. > A placement on a dynamic buffer too short to contain the placement is > never > reported however. See PR105948 > Yeah; looks like that will need some extra code in the analyzer to implement; you can ask the region_model what the capacity of the region is; do you have access to the required size of the region at the placement new call? If so then the implementation should be very similar as -Wanalyzer-out-of-bounds (or reuse it?) Dave >=20 > Thanks, > Benjamin >=20 > #include >=20 > struct A > { > int x =3D 4; > int y =3D 6; > }; >=20 > void test1() > { > int *x =3D ::new int; // true negative on -Wanalyzer-possible-null- > argument > int *arr =3D ::new int[3]; // true negative on > -Wanalyzer-possible-null-argument > A *a =3D ::new A(); // false positive -Wanalyzer-possible-null-argument > (a > throwing new cannot returns null) > ::delete a; > ::delete x; > ::delete[] arr; > } >=20 > void test_allocators_mismatch() > { > int *a =3D ::new int; > int *b =3D ::new int[3]; >=20 > ::delete[] a; /* true positive -Wanalyzer-mismatching-deallocation > flagged > */ > ::delete b; /* true positive -Wanalyzer-mismatching-deallocation > flagged */ > } >=20 > // From clang core.uninitialized.NewArraySize > void test_garbage_new_array() > { > int n; > int *arr =3D ::new int[n]; /* true positive > -Wanalyzer-use-of-uninitialized-value reported for 'n' */ > /* however nothing is reported for 'arr', even with > '-fno-analyzer-suppress-followups', one could expect a specific > warning */ > ::delete[] arr; /* no warnings here either */ > } >=20 > void test_placement() > { > void *chunk =3D ::operator new(20); // true negative > -Wanalyzer-possible-null-dereference > A *a =3D ::new (chunk) A(); > a->~A(); > ::operator delete(chunk); > } >=20 > void test_delete_placement() > { > A *a =3D ::new A; // false positive -Wanalyzer-possible-null-argument > (throwing new) > int *z =3D ::new (&a->y) int; > a->~A(); // deconstruct properly > ::operator delete(a); > ::operator delete(z); // nothing from analyzer but got > -Wfree-nonheap-object, even though analyzer also has > Wanalyzer-free-of-non-heap > } >=20 > void test_write_placement_after_delete() > { > short *s =3D ::new short; > long *lp =3D ::new (s) long; > ::delete s; > *lp =3D 12; // true positive -Wanalyzer-use-after-free flagged, as well > as a > wrong -Wanalyzer-null-dereference of lp > } >=20 > void test_read_placement_after_delete() > { > short *s =3D ::new short; > long *lp =3D ::new (s) long; > ::delete s; > long m =3D *lp; // true positive -Wanalyzer-use-after-free flagged, as > well > as a wrong -Wanalyzer-null-dereference of lp > } >=20 > void test_use_placement_after_destruction() > { > A a; > int *lp =3D ::new (&a.y) int; > a.~A(); > int m =3D *lp; /* true positive -Wanalyzer-use-of-uninitialized-value, > nothing about use-after-delete though */ > } >=20 > // From clang cplusplus.PlacementNewChecker > void test_placement_size_static() > { > short s; > long *lp =3D ::new (&s) long; /* nothing from analyzer, but still got > -Wplacement-new=3D */ > } >=20 > void test_placement_size_dynamic() > { > short *s =3D ::new short; > long *lp =3D ::new (s) long; // Nothing reported here at all, would > expect a > -Wanalyzer-placement-new=3D > ::delete s; > } >=20 > void test_placement_null() > { > int *x =3D nullptr; > int *p =3D ::new (x) int; // Placement new on NULL is undefined, yet > nothing > is reported. > ::operator delete(x); > } >=20 > void test_initialization_through_placement() > { > int x; > int *p =3D ::new (&x) int; > *p =3D 10; > int z =3D x + 2; // Everything is fine, no warning emitted > }