diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index a9ef9aced67e3..50286f2fd32a8 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -127,6 +127,11 @@ ANALYZER_OPTION(bool, MayInlineCXXStandardLibrary, "c++-stdlib-inlining", "considered for inlining.", true) +ANALYZER_OPTION(bool, ModelPthreads, "model-pthreads", + "Model Pthreads if enabled - default is disabled ", + false + ) + ANALYZER_OPTION(bool, MayInlineCXXAllocator, "c++-allocator-inlining", "Whether or not allocator and deallocator calls may be " "considered for inlining.", diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 25e28adaee1ad..66f94ff4905a9 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -1296,6 +1296,7 @@ static bool isTrivialObjectAssignment(const CallEvent &Call) { void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, const CallEvent &CallTemplate, const EvalCallOptions &CallOpts) { + AnalyzerOptions &Opts = AMgr.getAnalyzerOptions(); // Make sure we have the most recent state attached to the call. ProgramStateRef State = Pred->getState(); CallEventRef<> Call = CallTemplate.cloneWithState(State); @@ -1322,7 +1323,7 @@ void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, // TODO: make this a proper mode // Special case thread creation - if (isThread(*Call)) { + if (isThread(*Call) && Opts.ModelPthreads) { llvm::errs() << "Hijacking pthread_create(3)\n"; threadBifurcate(*Call, D, Bldr, Pred, State); return; diff --git a/clang/test/Analysis/SD-tests/thread-modeling-inline.c b/clang/test/Analysis/SD-tests/thread-modeling-inline.c index 566f5f1781d00..a4432ec47f04c 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-inline.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-inline.c @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) enum bool { diff --git a/clang/test/Analysis/SD-tests/thread-modeling-inline2.c b/clang/test/Analysis/SD-tests/thread-modeling-inline2.c index 1241d77ad9bf8..af052b285a854 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-inline2.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-inline2.c @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) enum bool { diff --git a/clang/test/Analysis/SD-tests/thread-modeling-leak.c b/clang/test/Analysis/SD-tests/thread-modeling-leak.c index 5794612c08e7b..f669c85f057d3 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-leak.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-leak.c @@ -1,7 +1,7 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) diff --git a/clang/test/Analysis/SD-tests/thread-modeling-leak2.c b/clang/test/Analysis/SD-tests/thread-modeling-leak2.c index b903437950cc8..bb89b29414fdc 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-leak2.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-leak2.c @@ -1,7 +1,7 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) diff --git a/clang/test/Analysis/SD-tests/thread-modeling-null-deref.c b/clang/test/Analysis/SD-tests/thread-modeling-null-deref.c index b04a1816ce571..0e2c9581cc2ca 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-null-deref.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-null-deref.c @@ -1,6 +1,6 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) enum bool { diff --git a/clang/test/Analysis/SD-tests/thread-modeling-null-deref2.c b/clang/test/Analysis/SD-tests/thread-modeling-null-deref2.c index a8a945684b19b..2e5269dc6b07d 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-null-deref2.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-null-deref2.c @@ -1,6 +1,6 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) enum bool { diff --git a/clang/test/Analysis/SD-tests/thread-modeling-path-dependent-leak.c b/clang/test/Analysis/SD-tests/thread-modeling-path-dependent-leak.c index 03c0dc9079df4..8485e2d454252 100644 --- a/clang/test/Analysis/SD-tests/thread-modeling-path-dependent-leak.c +++ b/clang/test/Analysis/SD-tests/thread-modeling-path-dependent-leak.c @@ -1,7 +1,7 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection -analyzer-config model-pthreads=true #define NULL ((void*) 0) diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index d5eb790b82f23..24c66e58c59fd 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -99,6 +99,7 @@ // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep // CHECK-NEXT: model-path = "" +// CHECK-NEXT: model-pthreads = false // CHECK-NEXT: notes-as-events = false // CHECK-NEXT: nullability:NoDiagnoseCallsToSystemHeaders = false // CHECK-NEXT: objc-inlining = true @@ -126,6 +127,7 @@ // CHECK-NEXT: suppress-c++-stdlib = true // CHECK-NEXT: suppress-inlined-defensive-checks = true // CHECK-NEXT: suppress-null-return-paths = true +// CHECK-NEXT: thread-aware = true // CHECK-NEXT: track-conditions = true // CHECK-NEXT: track-conditions-debug = false // CHECK-NEXT: unix.DynamicMemoryModeling:AddNoOwnershipChangeNotes = true diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index c70aeb21ab045..0d82b06a4ddae 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -7,6 +7,7 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: // CHECK-NEXT: apiModeling.Errno +// CHECK-NEXT: apiModeling.Thread // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.TrustReturnsNonnull // CHECK-NEXT: apiModeling.llvm.CastValue diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index faf0a8f19d919..2029cf3672df2 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -15,6 +15,7 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: // CHECK-NEXT: apiModeling.Errno +// CHECK-NEXT: apiModeling.Thread // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.TrustReturnsNonnull // CHECK-NEXT: apiModeling.llvm.CastValue