From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [IPv6:2a00:1450:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id BF3733858D28 for ; Thu, 4 May 2023 10:06:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BF3733858D28 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-ej1-x636.google.com with SMTP id a640c23a62f3a-94f1d0d2e03so42508566b.0 for ; Thu, 04 May 2023 03:06:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683194803; x=1685786803; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=GEidwpfiP1DCyzdVK5Tyka2uUVXEoDYfbN9GDpSE1CA=; b=EOKrLqzsaVZ5jInVN1/WYM9ATLrgXQQEVSbgFlk6saOVTBTjnn+cnU2+EgSTEvoq7t jYGS1F/cJBAS5odcEE+3YiXm+pcgImXBBPaIfCU1HGLfyQpX5nbpJbXTI6vbpLGQ9yoD 4yfSiZysU+EP7nM7UiXxZLGldxD1rq1mzIEiNsSBpaav/3hu+xhibVC5G67F5u/npJQK 1nGlDwYC7MVGXjBGy4+83yhdzOHYrYdEWwWzFMCh/9b+lSs9PPZrftZUavruulT6EqvP 7zChmHR6G2+hkJwhmLOZoIfovEdFhpj63ijQJT2pDZiqL3/G/Vl0jkCKREGLoPesWhBs YxwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683194803; x=1685786803; 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=GEidwpfiP1DCyzdVK5Tyka2uUVXEoDYfbN9GDpSE1CA=; b=RSXkvnvtZdYAwU5w+DQn09pvi6QL6KQ+dQC2joFKYPq/He2dtZM0JHkdK4GuFDKbjF Ufr3a4GtFWHr4Hejy7almwP1N27kghnkZzWy1YwQtbiyshdBe/Tpu3/D7VP/iLg0ZQbL YCxpwFpbJWfyCGc21LSmJ/NgWsB6XMXI+xQD4cR7x4iNfzLLS1ICv43AkjBCzdryNqmr BHK2RITrCIOLsV56FZQAL0VQWKPi3uXG7Fja20QgcR8FVYSIQX5CgZKVFhVu+abaFlqz e32bvljCfukbBO4CSpU7HEHFOqAN+OzfmOe2AUBJYP2Z+SIrZ64CNcUR87FbMgIfXd9O DdEg== X-Gm-Message-State: AC+VfDwB1hoKA+MMulRZhsY8jD/VaX1NCdU+bEEZMLo0ZchXaKlbwAa3 6yNbZ7VYcixtUY0+Nu/jS/badywiTqnaHsLjHsPeV0kJnrQ= X-Google-Smtp-Source: ACHHUZ4WptFuACOrgSkNyW3retwKMRZfcrMnhYenavtKVMBg+8YstIn/4qUajKe1BS6c88wVKsmOgDsVMWtKDJ9MfzM= X-Received: by 2002:a17:906:fe44:b0:94a:4fc5:4c2e with SMTP id wz4-20020a170906fe4400b0094a4fc54c2emr6246971ejb.49.1683194803383; Thu, 04 May 2023 03:06:43 -0700 (PDT) MIME-Version: 1.0 References: <7a44d8e8-19aa-79f7-f018-7d976b258ac7@gjlay.de> In-Reply-To: <7a44d8e8-19aa-79f7-f018-7d976b258ac7@gjlay.de> From: Jonathan Wakely Date: Thu, 4 May 2023 11:06:32 +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 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);