<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">On Jan 18, 2018, at 19:28, Friedman, Eli <<a href="mailto:efriedma@codeaurora.org" class="">efriedma@codeaurora.org</a>> wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class="">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">
<div text="#000000" bgcolor="#FFFFFF" class="">
<div class="moz-cite-prefix">On 1/18/2018 6:54 PM, Volodymyr Sapsai
via cfe-dev wrote:<br class="">
</div>
<blockquote type="cite" cite="mid:5D6EA6DF-FC9C-400A-96F7-956C20F4FA00@apple.com" class="">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">
Hello all,
<div class=""><br class="">
</div>
<div class="">I was investigating the bug <a href="https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4985" class="" moz-do-not-send="true">Heap-use-after-free in
clang::APValue::swap</a> which corresponds to the more
human-friendly form</div>
<div class=""><br class="">
</div>
<div class="">
<div class="">struct S {</div>
<div class=""> union {</div>
<div class=""> int i = i = 3;</div>
<div class=""> };</div>
<div class=""> constexpr S() {}</div>
<div class="">};</div>
<div class="">static_assert(S().i == 3, "”);</div>
</div>
<div class=""><br class="">
</div>
<div class="">When you compile this example with</div>
<div class="">clang -std=c++14 -fsyntax-only</div>
<div class=""><br class="">
</div>
<div class="">it crashes Clang 5.0.0, 4.0.0, 3.9.0 and running
with ASAN shows there is use after free in APValue hierarchy
caused by the `i` on the right hand side. If anybody is
interested I can provide more details about the mechanism of the
crash but it’s not important for the question I have.</div>
<div class=""><br class="">
</div>
<div class="">Should Clang accept such code at all according to
C++14 constexpr evaluation rules? GCC 7.2 rejects it, Clang ToT
with -std=c++11 rejects it too. Also it would be helpful to shed
some light on the differences between C++11 and C++14 for this
example as for `int i = i;` and -std=c++11 Clang hits the
assertion</div>
</blockquote>
<br class="">
The constexpr evaluation rules got substantially rewritten for C++14
(assignment wasn't allowed at all in C++11).<br class="">
<br class="">
Let's work through some cases. Consider the following:<br class="">
<br class="">
struct S {<br class="">
int i = 2;<br class="">
int j = i = 3;<br class="">
constexpr S() {}<br class="">
};<br class="">
static_assert(S().i == 3, "");<br class="">
<br class="">
Both clang and gcc accept this because assignment is generally
allowed in constant expressions.<br class="">
<br class="">
How about the following?<br class="">
<br class="">
struct S {<br class="">
int i = i = 3;<br class="">
constexpr S() {}<br class="">
};<br class="">
static_assert(S().i == 3, "");<br class="">
<br class="">
The relevant standard text is that constant evaluation doesn't allow
"modification of an object (8.5.18, 8.5.1.6, 8.5.2.2) unless it is
applied to a non-volatile lvalue of literal type that refers to a
non-volatile object whose lifetime began within the evaluation of
e". gcc accepts this, clang rejects it because it thinks the
lifetime of i doesn't start until after it's initialized. clang's
interpretation seems reasonable.<br class="">
<br class="">
Then we come to your testcase, with the anonymous union. I don't
think the addition of the anonymous union changes the analysis in
any significant way.<br class="">
<br class="">
-Eli<br class="">
<pre class="moz-signature" cols="72">--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project</pre>
</div>
</div></blockquote></div><div class="">Thank you, Eli. Lifetime explanation is useful and helps to grasp the difference between GCC and Clang.</div></body></html>