Skip to content

Commit 7330822

Browse files
authored
Fix clangsa on LLVM 10 (#37828)
* [GCChecker] Fix assertion We were associating a symbol with a `void` location. This is illegal, but happened to let us keep track of arraylist entries. Stop that abuse by manually modeling indexing into arraylist and fix the GCChecker assertion. * Backport LLVM 10 clangsa patch from Yggdrasil
1 parent b40355c commit 7330822

File tree

5 files changed

+45
-5
lines changed

5 files changed

+45
-5
lines changed

deps/llvm.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ $(eval $(call LLVM_PATCH,llvm-D84031)) # remove for LLVM 12
491491
$(eval $(call LLVM_PATCH,llvm-10-D85553)) # remove for LLVM 12
492492
$(eval $(call LLVM_PATCH,llvm-10-r_aarch64_prel32)) # remove for LLVM 12
493493
$(eval $(call LLVM_PATCH,llvm-10-r_ppc_rel)) # remove for LLVM 12
494+
$(eval $(call LLVM_PATCH,llvm-10-unique_function_clang-sa))
494495
ifeq ($(BUILD_LLVM_CLANG),1)
495496
$(eval $(call LLVM_PATCH,llvm-D88630-clang-cmake))
496497
endif
@@ -508,6 +509,7 @@ $(eval $(call LLVM_PATCH,llvm-julia-tsan-custom-as))
508509
$(eval $(call LLVM_PATCH,llvm-D80101)) # remove for LLVM 12
509510
$(eval $(call LLVM_PATCH,llvm-D84031)) # remove for LLVM 12
510511
$(eval $(call LLVM_PATCH,llvm-10-D85553)) # remove for LLVM 12
512+
$(eval $(call LLVM_PATCH,llvm-10-unique_function_clang-sa))
511513
ifeq ($(BUILD_LLVM_CLANG),1)
512514
$(eval $(call LLVM_PATCH,llvm-D88630-clang-cmake))
513515
endif
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
From 1fa6efaa946243004c45be92e66b324dc980df7d Mon Sep 17 00:00:00 2001
2+
From: Valentin Churavy <v.churavy@gmail.com>
3+
Date: Thu, 17 Sep 2020 23:22:45 +0200
4+
Subject: [PATCH] clang-sa can't determine that !RHS implies !LHS
5+
6+
---
7+
llvm/include/llvm/ADT/FunctionExtras.h | 2 ++
8+
1 file changed, 2 insertions(+)
9+
10+
diff --git a/include/llvm/ADT/FunctionExtras.h b/include/llvm/ADT/FunctionExtras.h
11+
index 121aa527a5d..b9b6d829b14 100644
12+
--- a/include/llvm/ADT/FunctionExtras.h
13+
+++ b/include/llvm/ADT/FunctionExtras.h
14+
@@ -193,9 +193,11 @@ public:
15+
// Copy the callback and inline flag.
16+
CallbackAndInlineFlag = RHS.CallbackAndInlineFlag;
17+
18+
+#ifndef __clang_analyzer__
19+
// If the RHS is empty, just copying the above is sufficient.
20+
if (!RHS)
21+
return;
22+
+#endif
23+
24+
if (!isInlineStorage()) {
25+
// The out-of-line case is easiest to move.
26+
--
27+
2.28.0
28+

src/clangsa/GCChecker.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,15 +1030,15 @@ SymbolRef GCChecker::getSymbolForResult(const Expr *Result,
10301030
const ValueState *OldValS,
10311031
ProgramStateRef &State,
10321032
CheckerContext &C) const {
1033+
QualType QT = Result->getType();
1034+
if (!QT->isPointerType() || QT->getPointeeType()->isVoidType())
1035+
return nullptr;
10331036
auto ValLoc = State->getSVal(Result, C.getLocationContext()).getAs<Loc>();
10341037
if (!ValLoc) {
10351038
return nullptr;
10361039
}
10371040
SVal Loaded = State->getSVal(*ValLoc);
10381041
if (Loaded.isUnknown() || !Loaded.getAsSymbol()) {
1039-
QualType QT = Result->getType();
1040-
if (!QT->isPointerType())
1041-
return nullptr;
10421042
if (OldValS || GCChecker::isGCTracked(Result)) {
10431043
Loaded = C.getSValBuilder().conjureSymbolVal(
10441044
nullptr, Result, C.getLocationContext(), Result->getType(),

src/module.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,24 @@ typedef struct _modstack_t {
258258

259259
static jl_binding_t *jl_get_binding_(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, modstack_t *st);
260260

261+
static inline jl_module_t *module_usings_getidx(jl_module_t *m JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT;
262+
263+
#ifndef __clang_analyzer__
264+
// The analyzer doesn't like looking through the arraylist, so just model the
265+
// access for it using this function
266+
static inline jl_module_t *module_usings_getidx(jl_module_t *m JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT {
267+
return (jl_module_t*)m->usings.items[i];
268+
}
269+
#endif
270+
261271
// find a binding from a module's `usings` list
262272
// called while holding m->lock
263273
static jl_binding_t *using_resolve_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, modstack_t *st, int warn)
264274
{
265275
jl_binding_t *b = NULL;
266276
jl_module_t *owner = NULL;
267277
for(int i=(int)m->usings.len-1; i >= 0; --i) {
268-
jl_module_t *imp = (jl_module_t*)m->usings.items[i];
278+
jl_module_t *imp = module_usings_getidx(m, i);
269279
// TODO: make sure this can't deadlock
270280
JL_LOCK(&imp->lock);
271281
jl_binding_t *tempb = _jl_get_module_binding(imp, var);

test/clangsa/MissingRoots.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ jl_module_t *propagation(jl_module_t *m JL_PROPAGATES_ROOT);
329329
void module_member(jl_module_t *m)
330330
{
331331
for(int i=(int)m->usings.len-1; i >= 0; --i) {
332-
jl_module_t *imp = (jl_module_t*)m->usings.items[i];
332+
jl_module_t *imp = propagation(m);
333333
jl_gc_safepoint();
334334
look_at_value((jl_value_t*)imp);
335335
jl_module_t *prop = propagation(imp);

0 commit comments

Comments
 (0)