<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">On 1/18/2018 6:54 PM, Volodymyr Sapsai
via cfe-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:5D6EA6DF-FC9C-400A-96F7-956C20F4FA00@apple.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
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>
The constexpr evaluation rules got substantially rewritten for C++14
(assignment wasn't allowed at all in C++11).<br>
<br>
Let's work through some cases. Consider the following:<br>
<br>
struct S {<br>
int i = 2;<br>
int j = i = 3;<br>
constexpr S() {}<br>
};<br>
static_assert(S().i == 3, "");<br>
<br>
Both clang and gcc accept this because assignment is generally
allowed in constant expressions.<br>
<br>
How about the following?<br>
<br>
struct S {<br>
int i = i = 3;<br>
constexpr S() {}<br>
};<br>
static_assert(S().i == 3, "");<br>
<br>
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>
<br>
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>
<br>
-Eli<br>
<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>
</body>
</html>