From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by sourceware.org (Postfix) with ESMTPS id 8B8F43858D33 for ; Thu, 4 May 2023 10:26:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8B8F43858D33 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-ed1-x530.google.com with SMTP id 4fb4d7f45d1cf-50bc1612940so534178a12.2 for ; Thu, 04 May 2023 03:26:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683195967; x=1685787967; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=klsiNymwIA9FICZRaThXGbNWjd2f2Ezahmdag6TkYBo=; b=DixDQ3dkZ/tlvx221LgpVz85Quqc+0Wxj6p6q3sFgts2fiiv1AbEGPNSo8jGywICz0 P9U8ZytS35vaaAp+h9PaCfTDWLe6hP7/YvCtnpVhtqBpfAHFxJAg7OkgO6PtFtEdtRmM o7uVwqWQx9woZUBrCSNgapjOzZE1T7q/Nf5QOUJG7r/Zyap6qQhIuUHPQky2z/0fvvQL +t/jt4y+casz08ZG8y1wrbfzp7ZIP9MAWr7LIjxSR+tU1Kw5WXbtipgMfo4BL944DRSe Qg1iqUx+jUvdBkYFgvzkj6Bfic71gPScw9sVRyUJr+QZSH18hak1LgTmOAhxeZJL+u1J oDAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683195967; x=1685787967; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=klsiNymwIA9FICZRaThXGbNWjd2f2Ezahmdag6TkYBo=; b=JGaZ0ApwyLC0M1PL+MCGoHEsgXYLWk9N4NpTMH5WEoLcCZm8Tx8DrqnIX6dtYg3jtD DFTonrWfmssWS4gQ8/Ps+Njg+giFQ3VL3HZN9D2b3fXgGGCo/mGhY+1otQYel0ASctAH nw9Fhdcce0G7Lp7FTnbMbV/Fr7Scli09TjpsAlNZY0Kv9e0Xc+B2DVXFuID4QLqiSeK9 Fu6qhfu4YcKJzRhJ8cnIZy/7VTDhnBNoea19lIpq5+rK4kAZyh6aVzidH+b1XglGdMTz 1nBGgJu0dokpCG4/AdHMVXPgUywZZOeEsI8FiwDKydQHO8pMFNwUfYc10MXXGMOqy0X+ 0tTg== X-Gm-Message-State: AC+VfDw3VUK0N8T/hZhIk1DpITKSLx4RPG7yMT1tnC3ovmkhV7OT6bY+ Hfza9wk4hg3t/aLRtjJhbsuiq4CT2imw6rKEy6hVlR1UqHg= X-Google-Smtp-Source: ACHHUZ7Mi6P/dA6tMc+sNSGwd7PC9oGmn5bvzF5hn+CbCIZDlfTpu+F+a3w2Zo5Ur98VfQ8nPFsX8nU9d7L62zN53vM= X-Received: by 2002:a17:907:2d93:b0:94a:785e:6a46 with SMTP id gt19-20020a1709072d9300b0094a785e6a46mr6256883ejc.24.1683195967125; Thu, 04 May 2023 03:26:07 -0700 (PDT) MIME-Version: 1.0 References: <7a44d8e8-19aa-79f7-f018-7d976b258ac7@gjlay.de> In-Reply-To: From: Jonathan Wakely Date: Thu, 4 May 2023 11:25:55 +0100 Message-ID: Subject: Re: g++ problem with order of evaluation of arguments of delete. To: Georg-Johann Lay Cc: gcc-help@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-0.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,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: On Thu, 4 May 2023 at 11:12, Jonathan Wakely wrote: > > On Thu, 4 May 2023 at 11:06, Jonathan Wakely wrote: > > > > On Thu, 4 May 2023 at 10:46, Georg-Johann Lay wrote: > > > > > > Given the following C++ code: > > > > > > struct Lexer; > > > > > > struct Token > > > { > > > Lexer* const lexer_; > > > Token (Lexer *l) : lexer_(l) {} > > > ~Token() = default; > > > > > > Token() = delete; > > > Token (const Token&) = delete; > > > Token (Token&&) = delete; > > > void operator= (const Token&) = delete; > > > void operator= (Token&&) = delete; > > > }; > > > > > > struct Lexer > > > { > > > Token *token_; > > > Lexer() = default; > > > ~Lexer() { delete token_; } > > > > > > Lexer (const Lexer&) = delete; > > > Lexer (Lexer&&) = delete; > > > void operator= (const Lexer&) = delete; > > > void operator= (Lexer&&) = delete; > > > }; > > > > > > int main() > > > { > > > Lexer *lexer = new Lexer(); > > > Token *token = new Token (lexer); > > > lexer->token_ = token; > > > delete token->lexer_; > > > // delete lexer; // is OK > > > } > > > > > > When I compile this with g++ v11.3 (same with g++ from master from > > > 2023-04-20) and run > > > > > > $ g++ main-3.cpp -Os -W -Wall -Wextra -dumpbase "" -save-temps -dp && > > > ./a.out > > > > > > Segmentation fault (core dumped) > > > > > > The assembly shows that the generated code does two calls to "delete" > > > but just one call to "new", so it's clear something is going wrong. > > > > > > As far as I understand, the "delete token_" in ~Lexer is a sequence > > > point, so that dereferencing token in "delete->lexer_" must be sequenced > > > before calling ~Token ? > > > > > > Segmentation fault also occurs with -O0, but goes away when removing the > > > "const" in "Lexer* const lexer_;". > > > > > > My question: Is this a GCC problem, or a problem with the code and > > > sequence points? > > > > It's definitely a GCC bug. > > > > The code is compiled to something like: > > > > token->lexer_->~Lexer(); > > operator delete(token->lexer_); > > > > But that means that we evaluate 'token' twice, even though it's been > > invalidated by the destructor. It should be compiled to something more > > like: > > > > auto* p = token->lexer_; > > p->~Lexer(); > > operator delete(p); > > The C++ standard is clear, see [expr.delete] p4: > > "The cast-expression in a delete-expression shall be evaluated exactly once." > > That wording has been present since C++98. > > Please file a bug. The bug was already present in gcc 4.1.0, I didn't check anything older than r0-71179-gc6ff1944941b0c aka r105000