From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il1-x134.google.com (mail-il1-x134.google.com [IPv6:2607:f8b0:4864:20::134]) by sourceware.org (Postfix) with ESMTPS id D92453858C54 for ; Wed, 7 Jun 2023 17:19:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D92453858C54 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-il1-x134.google.com with SMTP id e9e14a558f8ab-33d0b7114a9so6882495ab.2 for ; Wed, 07 Jun 2023 10:19:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686158359; x=1688750359; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=fM5xJb7ObIRfYXoN9f3ulJAt73Zg8DilI4NTS+3nheI=; b=od3Oc+S4vfqQb4eRljlvw2ksh6nuVe1d7AcDOeL3zBQoKwrxSePTjj0eCFGr7qE1zO L+hsp4bhHACLZzq7XzwlC5mTcR2sIFfOimP4AB/Cz9b/rSqkUim40CyGwPSO3/EvSStU 2DJ2fsrTfTob+Dm2eXKvqvcBcLuIjisyRnUaJTZGF9mHteeBqHKspEIqZXVkFJDYK3lT WwDi+NefgWvOG6N9bXsyXINj+37kZE9kwvj1oJy0pCT+fX7E3tsh/pZM1lbzc5j0cmQW qh6GNiKRlV2tZ+xPoRRRhmdI/NWZDToCy6/3hqcjxrgXDpIZLpBLp7Ri0gH55k7MGv7N DogA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686158359; x=1688750359; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=fM5xJb7ObIRfYXoN9f3ulJAt73Zg8DilI4NTS+3nheI=; b=J5xuXpOdxbkPwfqWAWewBapFdaSGtpYZdMt3eqR15hoW6G+WUXuF8ldMohoObD6IPh kh/2iO+N8sKRSmJF0hXhEWtbGLPu9LzUJu7f9VE60PtCRRXZakYXm6HANU1ck134R5PT Pc12sE48dEd69mPdWv2vfh7FjORoUVyzhS+zty+ZfX97Shs6Dx2OxRZkOwPa2kBQVc6s NL7Knxrsa1GogIP52ayctOjljo0ORYVPnbZ4nW6NQwMNXRiqxRMdfvAiLGtJqDjY+MSV gCP+6pJ8jDYs7/9k9i1QXvBoc674cxBY3VSfmeJmTY4cYk4wO/UUHhWg7WHLuiFYB987 eiDQ== X-Gm-Message-State: AC+VfDzT8bPs2m4Jvvo+WlpSlQHrhLzOPEbA2KRwaOxAY+6FdhuFoAjF PTdpacEoDH1BeldkfnYw7xAZq8YP+iulm+eETgNmBMtj4pJWvoQ= X-Google-Smtp-Source: ACHHUZ5XzFhAHi4AjuDJ9dVN5qouAYEiACOziHl6zXSR8+lMS77KppqLwoHfSH12Bya2jbblQL0SE9fwZHGAi/K/SGI= X-Received: by 2002:a92:ce41:0:b0:33d:136f:249f with SMTP id a1-20020a92ce41000000b0033d136f249fmr6549392ilr.22.1686158358887; Wed, 07 Jun 2023 10:19:18 -0700 (PDT) MIME-Version: 1.0 From: Benjamin Priour Date: Wed, 7 Jun 2023 19:19:07 +0200 Message-ID: Subject: An overview of the analyzer support of the operator new To: gcc@gcc.gnu.org Cc: David Malcolm Content-Type: multipart/alternative; boundary="0000000000000444f505fd8d5602" X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,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: --0000000000000444f505fd8d5602 Content-Type: text/plain; charset="UTF-8" Hi, 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 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. You can also find a godbolt here. 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 Thanks, Benjamin #include struct A { int x = 4; int y = 6; }; void test1() { int *x = ::new int; // true negative on -Wanalyzer-possible-null-argument int *arr = ::new int[3]; // true negative on -Wanalyzer-possible-null-argument A *a = ::new A(); // false positive -Wanalyzer-possible-null-argument (a throwing new cannot returns null) ::delete a; ::delete x; ::delete[] arr; } void test_allocators_mismatch() { int *a = ::new int; int *b = ::new int[3]; ::delete[] a; /* true positive -Wanalyzer-mismatching-deallocation flagged */ ::delete b; /* true positive -Wanalyzer-mismatching-deallocation flagged */ } // From clang core.uninitialized.NewArraySize void test_garbage_new_array() { int n; int *arr = ::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 */ } void test_placement() { void *chunk = ::operator new(20); // true negative -Wanalyzer-possible-null-dereference A *a = ::new (chunk) A(); a->~A(); ::operator delete(chunk); } void test_delete_placement() { A *a = ::new A; // false positive -Wanalyzer-possible-null-argument (throwing new) int *z = ::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 } void test_write_placement_after_delete() { short *s = ::new short; long *lp = ::new (s) long; ::delete s; *lp = 12; // true positive -Wanalyzer-use-after-free flagged, as well as a wrong -Wanalyzer-null-dereference of lp } void test_read_placement_after_delete() { short *s = ::new short; long *lp = ::new (s) long; ::delete s; long m = *lp; // true positive -Wanalyzer-use-after-free flagged, as well as a wrong -Wanalyzer-null-dereference of lp } void test_use_placement_after_destruction() { A a; int *lp = ::new (&a.y) int; a.~A(); int m = *lp; /* true positive -Wanalyzer-use-of-uninitialized-value, nothing about use-after-delete though */ } // From clang cplusplus.PlacementNewChecker void test_placement_size_static() { short s; long *lp = ::new (&s) long; /* nothing from analyzer, but still got -Wplacement-new= */ } void test_placement_size_dynamic() { short *s = ::new short; long *lp = ::new (s) long; // Nothing reported here at all, would expect a -Wanalyzer-placement-new= ::delete s; } void test_placement_null() { int *x = nullptr; int *p = ::new (x) int; // Placement new on NULL is undefined, yet nothing is reported. ::operator delete(x); } void test_initialization_through_placement() { int x; int *p = ::new (&x) int; *p = 10; int z = x + 2; // Everything is fine, no warning emitted } --0000000000000444f505fd8d5602--