From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 121963 invoked by alias); 2 May 2017 10:17:45 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 121944 invoked by uid 89); 2 May 2017 10:17:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=no version=3.3.2 spammy=Freddie, H*i:sk:1493589, H*f:sk:1493589, freddie X-HELO: mail-io0-f169.google.com Received: from mail-io0-f169.google.com (HELO mail-io0-f169.google.com) (209.85.223.169) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 02 May 2017 10:17:43 +0000 Received: by mail-io0-f169.google.com with SMTP id a103so150695174ioj.1 for ; Tue, 02 May 2017 03:17:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=3/RWlQTqx+Sp+sm9y7XALDWbr7woL/zA4+0vS0kOFY4=; b=XkZheLroXbiZtE8o4ceJQGx5v7Hxlm7tHAaFpnOPq3A47EqqpBnqTdOTD/kk6JvyeV O/ajNhTxJd8Fjtp8rDphAb5BLOXsB1IskCSY47bqIaMjBaSD8x1InmqzxViTfCXDqRmr j112Jl0XlKJBt35pa0W6gF78oemCvn6/Nsks6YkhTTHw5mIgGvEdhskDlcqJ5E455YWQ wsSaexFuGiGirLDDKRRf1rjUkJvau3+hxV83MlVQlHvKTkwEiL5lGzGUZ8jw5j35v+j4 uX25kM8eciNtWAJUG14+fJFEDYuEl0FpVijpQve3nUcoI6fCP2iDU8S561TU8nEs0vD7 AIZg== X-Gm-Message-State: AN3rC/5ajdOngFkjuXjLjWaxyIWzVIolzEuVj+JNm30zUHaHb9rnxjwk Wv7ScuVw+6zUwJnCeR5CyWeRVALFzw== X-Received: by 10.157.33.98 with SMTP id l31mr11645517otd.245.1493720264008; Tue, 02 May 2017 03:17:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.157.51.83 with HTTP; Tue, 2 May 2017 03:17:43 -0700 (PDT) In-Reply-To: <1493589369.1268.4.camel@op.pl> References: <1493589369.1268.4.camel@op.pl> From: Richard Biener Date: Tue, 02 May 2017 10:17:00 -0000 Message-ID: Subject: =?UTF-8?Q?Re=3A_GCC_7=2C_aligned=5Fstorage_and_=E2=80=9Cdereferencing_type?= =?UTF-8?Q?=2Dpunned_pointer_will_break_strict=2Daliasing_rules=E2=80=9D?= To: Freddie Chopin Cc: GCC Development Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2017-05/txt/msg00013.txt.bz2 On Sun, Apr 30, 2017 at 11:56 PM, Freddie Chopin wrote: > Hello! > > A code that I wrote was warning-free in GCC 4.9, GCC 5 and GCC 6. It > was also warning-free with some older GCC 7 experimental snapshots (for > example 7-20170409). But in the most recent snapshot (including the > first RC), it started to produce a warning about aliasing. The code > basically boils down to this: > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > #include > > std::aligned_storage::type storage; > > int main() > { > *reinterpret_cast(&storage) = 42; > } > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > Compilation with latest GCC 7 RC: > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > $ g++ -Wall -O2 -c main.cpp > main.cpp: In function 'int main()': > main.cpp:7:34: warning: dereferencing type-punned pointer will break > strict-aliasing rules [-Wstrict-aliasing] > *reinterpret_cast(&storage) = 42; > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > (interesting observation is that the warning is not produced when > optimizations are disabled) > > Compilation with GCC 6 gives no warnings at all. > > Now I'm wondering, the code above definitely HAS type-punning, no > question about that, but isn't std::aligned_storage meant to be used > that way? > > For instance the example code given here on cppreference generally > produces no warning with GCC 7 but only because: > - std::string somehow is not affected, > - std::aligned_storage is accessed with an offset. > > http://en.cppreference.com/w/cpp/types/aligned_storage > > By changing std::string into int, removing offset access to > std::aligned_storage and removing irrelevant parts you get this: > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > #include > #include > #include > > template > class static_vector > { > // properly aligned uninitialized storage for N T's > typename std::aligned_storage::type data[N]; > std::size_t m_size = 0; > > public: > > // Access an object in aligned storage > const T& operator[](std::size_t pos) const > { > return *reinterpret_cast(data/*+pos*/); // <- note > here, offset access disabled > } > }; > > int main() > { > static_vector v1; > std::cout << v1[0] << '\n' << v1[1] << '\n'; > } > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > And this produces exactly the same warning: > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > main.cpp: In instantiation of 'const T& static_vector N>::operator[](std::size_t) const [with T = int; unsigned int N = 10; > std::size_t = unsigned int]': > main.cpp:24:22: required from here > main.cpp:17:16: warning: dereferencing type-punned pointer will break > strict-aliasing rules [-Wstrict-aliasing] > return *reinterpret_cast(data/*+pos*/); > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- > > So my question is - is this a bug or a feature? First of all the -Wstrict-aliasing warning is not very accurate. But this shows an issue with GCC 7 so please open a bugreport. Testcase without libstd++ headers: template struct aligned_storage { union type { unsigned char __data[_Len]; struct __attribute__((__aligned__((_Align)))) { } __align; }; }; aligned_storage::type storage; int main() { *reinterpret_cast(&storage) = 42; } and we warn from 525 && (set1 == 0 526 || (!alias_set_subset_of (set2, set1) 527 && !alias_sets_conflict_p (set1, set2)))) 528 { 529 warning (OPT_Wstrict_aliasing, "dereferencing type-punned " 530 "pointer will break strict-aliasing rules"); 531 return true; where set1 == 0 (of 'storage') and set2 == 1 (of 'int'). Not sure why we warn if set1 == 0 ... Richard. > Thanks in advance! > > Regards, > FCh > > BTW - I've also posted this question on stackoverflow > http://stackoverflow.com/questions/43711567/gcc-7-aligned-storage-and-dereferencing-type-punned-pointer-will-break-strict