<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Spurious -Wthread-safety warning in template class"
href="https://bugs.llvm.org/show_bug.cgi?id=45323">45323</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Spurious -Wthread-safety warning in template class
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>-New Bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>efriedma@quicinc.com
</td>
</tr>
<tr>
<th>CC</th>
<td>elizabeth.andrews@intel.com, htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>Testcase:
#include <mutex>
template <typename T>
struct X {
std::mutex mutex_;
void Run() {
auto guard = std::lock_guard{mutex_};
}
};
void (X<int>::*x)() = &X<int>::Run;
Command:
clang++ -stdlib=libc++ -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
-Wthread-safety -std=gnu++2a -fsyntax-only
Prints the following warning:
/tmp/build2.cpp:7:5: warning: releasing mutex 'guard' that was not held
[-Wthread-safety-analysis]
}
^
/tmp/build2.cpp:9:32: note: in instantiation of member function 'X<int>::Run'
requested here
void (X<int>::*x)() = &X<int>::Run;
^
1 warning generated.
godbolt link: <a href="https://godbolt.org/z/knYGyE">https://godbolt.org/z/knYGyE</a>
I think this regressed in <a href="https://github.com/llvm/llvm-project/commit/878a24ee">https://github.com/llvm/llvm-project/commit/878a24ee</a>.
(I haven't precisely verified it, but it's the only relevant commit around
that day.)
Diff in AST before template instantiation:
-| | `-VarDecl <col:9, col:44> col:14 guard 'auto' cinit
-| | `-CXXUnresolvedConstructExpr <col:22, col:44>
'std::lock_guard':'lock_guard' 'std::lock_guard':'lock_guard' list
-| | `-InitListExpr <col:37, col:44> 'void'
-| | `-MemberExpr <col:38> 'std::mutex':'std::__1::mutex' lvalue
->mutex_
-| | `-CXXThisExpr <col:38> 'X<T> *' implicit this
+| | `-VarDecl <col:9, col:44> col:14 guard
'std::__1::lock_guard<std::__1::mutex>':'std::__1::lock_guard<std::__1::mutex>'
cinit destroyed
+| | `-ExprWithCleanups <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>'
+| | `-CXXBindTemporaryExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' (CXXTemporary
)
+| | `-CXXTemporaryObjectExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' 'void
(std::__1::lock_guard<std::__1::mutex>::mutex_type &)' list
+| | `-MemberExpr <col:38> 'std::mutex':'std::__1::mutex' lvalue
->mutex_
+| | `-CXXThisExpr <col:38> 'X<T> *' implicit this
Diff in AST after template instantiation:
-| | `-CXXBindTemporaryExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' (CXXTemporary
)
-| | `-CXXTemporaryObjectExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' 'void
(std::__1::lock_guard<std::__1::mutex>::mutex_type &)' list
-| | `-MemberExpr <col:38> 'std::mutex':'std::__1::mutex' lvalue
->mutex_
-| | `-CXXThisExpr <col:38> 'X<int> *' implicit this
+| | `-CXXFunctionalCastExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' functional
cast to std::lock_guard <ConstructorConversion>
+| | `-CXXBindTemporaryExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' (CXXTemporary
)
+| | `-CXXConstructExpr <col:22, col:44>
'std::lock_guard<mutex>':'std::__1::lock_guard<std::__1::mutex>' 'void
(std::__1::lock_guard<std::__1::mutex>::mutex_type &)'
+| | `-MemberExpr <col:38> 'std::mutex':'std::__1::mutex'
lvalue ->mutex_
+| | `-CXXThisExpr <col:38> 'X<int> *' implicit this
The AST after template instantiation looks suspicious. But I'm not sure
whether the difference is actually a miscompile, or it's a legitimate variation
that's confusing the thread safety analysis.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>