[cfe-commits] r163004 - in /cfe/trunk: docs/analyzer/IPA.txt include/clang/StaticAnalyzer/Core/AnalyzerOptions.h lib/StaticAnalyzer/Core/AnalyzerOptions.cpp lib/StaticAnalyzer/Core/CMakeLists.txt lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp test/Analysis/base-init.cpp test/Analysis/ctor-inlining.mm test/Analysis/dtor.cpp test/Analysis/initializer.cpp test/Analysis/inline.cpp test/Analysis/method-call.cpp
Jordan Rose
jordan_rose at apple.com
Fri Aug 31 10:06:49 PDT 2012
Author: jrose
Date: Fri Aug 31 12:06:49 2012
New Revision: 163004
URL: http://llvm.org/viewvc/llvm-project?rev=163004&view=rev
Log:
[analyzer] Though C++ inlining is enabled, don't inline ctors and dtors.
More generally, this adds a new configuration option 'c++-inlining', which
controls which C++ member functions can be considered for inlining. This
uses the new -analyzer-config table, so the cc1 arguments will look like this:
... -analyzer-config c++-inlining=[none|methods|constructors|destructors]
Note that each mode implies that all the previous member function kinds
will be inlined as well; it doesn't make sense to inline destructors
without inlining constructors, for example.
The default mode is 'methods'.
Added:
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
Modified:
cfe/trunk/docs/analyzer/IPA.txt
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/test/Analysis/base-init.cpp
cfe/trunk/test/Analysis/ctor-inlining.mm
cfe/trunk/test/Analysis/dtor.cpp
cfe/trunk/test/Analysis/initializer.cpp
cfe/trunk/test/Analysis/inline.cpp
cfe/trunk/test/Analysis/method-call.cpp
Modified: cfe/trunk/docs/analyzer/IPA.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/IPA.txt?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/docs/analyzer/IPA.txt (original)
+++ cfe/trunk/docs/analyzer/IPA.txt Fri Aug 31 12:06:49 2012
@@ -1,6 +1,9 @@
Inlining
========
+There are several options that control which calls the analyzer will consider for
+inlining. The major one is -analyzer-ipa:
+
-analyzer-ipa=none - All inlining is disabled. This is the only mode available
in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
@@ -25,6 +28,23 @@
Currently, -analyzer-ipa=dynamic-bifurcate is the default mode.
+
+A second setting, c++-inlining, controls which C++ member functions may be
+inlined. This option uses the analyzer's configuration table, so it is specified
+as shown here:
+
+ -analyzer-config c++-inlining=[none | methods | constructors | destructors]
+
+Each of these modes implies that all the previous member function kinds will be
+inlined as well; it doesn't make sense to inline destructors without inlining
+constructors, for example.
+
+The default c++-inlining mode is 'methods', meaning only regular member
+functions and overloaded operators will be inlined. Note that no C++ member
+functions will be inlined under -analyzer-ipa=none or
+-analyzer-ipa=basic-inlining.
+
+
Basics of Implementation
-----------------------
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Aug 31 12:06:49 2012
@@ -76,6 +76,31 @@
NumInliningModes
};
+/// \brief Describes the different kinds of C++ member functions which can be
+/// considered for inlining by the analyzer.
+///
+/// These options are cumulative; enabling one kind of member function will
+/// enable all kinds with lower enum values.
+enum CXXInlineableMemberKind {
+ // Uninitialized = 0,
+
+ /// A dummy mode in which no C++ inlining is enabled.
+ CIMK_None = 1,
+
+ /// Refers to regular member function and operator calls.
+ CIMK_MemberFunctions,
+
+ /// Refers to constructors (implicit or explicit).
+ ///
+ /// Note that a constructor will not be inlined if the corresponding
+ /// destructor is non-trivial.
+ CIMK_Constructors,
+
+ /// Refers to destructors (implicit or explicit).
+ CIMK_Destructors
+};
+
+
class AnalyzerOptions : public llvm::RefCountedBase<AnalyzerOptions> {
public:
typedef llvm::StringMap<std::string> ConfigTable;
@@ -139,8 +164,19 @@
/// \brief The mode of function selection used during inlining.
AnalysisInliningMode InliningMode;
+private:
+ /// Controls which C++ member functions will be considered for inlining.
+ CXXInlineableMemberKind CXXMemberInliningMode;
+
+public:
+ /// Returns the option controlling which C++ member functions will be
+ /// considered for inlining.
+ ///
+ /// \sa CXXMemberInliningMode
+ bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
+
public:
- AnalyzerOptions() {
+ AnalyzerOptions() : CXXMemberInliningMode() {
AnalysisStoreOpt = RegionStoreModel;
AnalysisConstraintsOpt = RangeConstraintsModel;
AnalysisDiagOpt = PD_HTML;
Added: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=163004&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (added)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Fri Aug 31 12:06:49 2012
@@ -0,0 +1,48 @@
+//===-- AnalyzerOptions.cpp - Analysis Engine Options -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains special accessors for analyzer configuration options
+// with string representations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace clang;
+
+bool
+AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const {
+ if (IPAMode < Inlining)
+ return false;
+
+ if (!CXXMemberInliningMode) {
+ static const char *ModeKey = "c++-inlining";
+ std::string ModeStr = Config.lookup(ModeKey);
+
+ CXXInlineableMemberKind &MutableMode =
+ const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);
+
+ MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
+ .Case("", CIMK_MemberFunctions)
+ .Case("constructors", CIMK_Constructors)
+ .Case("destructors", CIMK_Destructors)
+ .Case("none", CIMK_None)
+ .Case("methods", CIMK_MemberFunctions)
+ .Default(CXXInlineableMemberKind());
+
+ if (!MutableMode) {
+ // FIXME: We should emit a warning here about an unknown inlining kind,
+ // but the AnalyzerOptions doesn't have access to a diagnostic engine.
+ MutableMode = CIMK_None;
+ }
+ }
+
+ return CXXMemberInliningMode >= K;
+}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt Fri Aug 31 12:06:49 2012
@@ -3,6 +3,7 @@
add_clang_library(clangStaticAnalyzerCore
APSIntType.cpp
AnalysisManager.cpp
+ AnalyzerOptions.cpp
BasicValueFactory.cpp
BlockCounter.cpp
BugReporter.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Fri Aug 31 12:06:49 2012
@@ -316,21 +316,6 @@
}}
-static bool shouldInlineCXX(AnalysisManager &AMgr) {
- switch (AMgr.options.IPAMode) {
- case None:
- case BasicInlining:
- return false;
- case Inlining:
- case DynamicDispatch:
- case DynamicDispatchBifurcate:
- return true;
- case NumIPAModes:
- llvm_unreachable("not actually a valid option");
- }
- llvm_unreachable("bogus IPAMode");
-}
-
bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
NodeBuilder &Bldr, ExplodedNode *Pred,
ProgramStateRef State) {
@@ -340,17 +325,19 @@
const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
const LocationContext *ParentOfCallee = 0;
+ const AnalyzerOptions &Opts = getAnalysisManager().options;
+
// FIXME: Refactor this check into a hypothetical CallEvent::canInline.
switch (Call.getKind()) {
case CE_Function:
break;
case CE_CXXMember:
case CE_CXXMemberOperator:
- if (!shouldInlineCXX(getAnalysisManager()))
+ if (!Opts.mayInlineCXXMemberFunction(CIMK_MemberFunctions))
return false;
break;
case CE_CXXConstructor: {
- if (!shouldInlineCXX(getAnalysisManager()))
+ if (!Opts.mayInlineCXXMemberFunction(CIMK_Constructors))
return false;
const CXXConstructorCall &Ctor = cast<CXXConstructorCall>(Call);
@@ -369,15 +356,17 @@
if (isa<CXXNewExpr>(Parent))
return false;
+ // Inlining constructors requires including initializers in the CFG.
+ const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
+ assert(ADC->getCFGBuildOptions().AddInitializers && "No CFG initializers");
+
// If the destructor is trivial, it's always safe to inline the constructor.
if (Ctor.getDecl()->getParent()->hasTrivialDestructor())
break;
- // For other types, only inline constructors if we built the CFGs for the
- // destructor properly.
- const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
- assert(ADC->getCFGBuildOptions().AddInitializers && "No CFG initializers");
- if (!ADC->getCFGBuildOptions().AddImplicitDtors)
+ // For other types, only inline constructors if destructor inlining is
+ // also enabled.
+ if (!Opts.mayInlineCXXMemberFunction(CIMK_Destructors))
return false;
// FIXME: This is a hack. We don't handle temporary destructors
@@ -389,14 +378,12 @@
break;
}
case CE_CXXDestructor: {
- if (!shouldInlineCXX(getAnalysisManager()))
+ if (!Opts.mayInlineCXXMemberFunction(CIMK_Destructors))
return false;
- // Only inline constructors and destructors if we built the CFGs for them
- // properly.
+ // Inlining destructors requires building the CFG correctly.
const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
- if (!ADC->getCFGBuildOptions().AddImplicitDtors)
- return false;
+ assert(ADC->getCFGBuildOptions().AddImplicitDtors && "No CFG destructors");
const CXXDestructorCall &Dtor = cast<CXXDestructorCall>(Call);
@@ -408,9 +395,6 @@
break;
}
case CE_CXXAllocator:
- if (!shouldInlineCXX(getAnalysisManager()))
- return false;
-
// Do not inline allocators until we model deallocators.
// This is unfortunate, but basically necessary for smart pointers and such.
return false;
Modified: cfe/trunk/test/Analysis/base-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/base-init.cpp?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/base-init.cpp (original)
+++ cfe/trunk/test/Analysis/base-init.cpp Fri Aug 31 12:06:49 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -verify %s
void clang_analyzer_eval(bool);
Modified: cfe/trunk/test/Analysis/ctor-inlining.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctor-inlining.mm?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/ctor-inlining.mm (original)
+++ cfe/trunk/test/Analysis/ctor-inlining.mm Fri Aug 31 12:06:49 2012
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
struct Wrapper {
__strong id obj;
@@ -86,4 +87,19 @@
}
}
+namespace TemporaryConstructor {
+ class BoolWrapper {
+ public:
+ BoolWrapper() {
+ clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+ value = true;
+ }
+ bool value;
+ };
+ void test() {
+ // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined.
+ if (BoolWrapper().value)
+ return;
+ }
+}
Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Fri Aug 31 12:06:49 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=destructors -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
Modified: cfe/trunk/test/Analysis/initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initializer.cpp?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/initializer.cpp (original)
+++ cfe/trunk/test/Analysis/initializer.cpp Fri Aug 31 12:06:49 2012
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -cfg-add-implicit-dtors -std=c++11 -verify %s
-
-// We don't inline constructors unless we have destructors turned on.
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
void clang_analyzer_eval(bool);
@@ -65,13 +63,13 @@
void testReferenceMember() {
int *p = 0;
- RefWrapper X(p); // expected-warning at 61 {{Dereference of null pointer}}
+ RefWrapper X(p); // expected-warning at -7 {{Dereference of null pointer}}
}
void testReferenceMember2() {
int *p = 0;
// FIXME: We should warn here, since we're creating the reference here.
- RefWrapper X(*p); // expected-warning at 62 {{Dereference of null pointer}}
+ RefWrapper X(*p); // expected-warning at -12 {{Dereference of null pointer}}
}
Modified: cfe/trunk/test/Analysis/inline.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.cpp (original)
+++ cfe/trunk/test/Analysis/inline.cpp Fri Aug 31 12:06:49 2012
@@ -267,20 +267,3 @@
clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
}
}
-
-namespace TemporaryConstructor {
- class BoolWrapper {
- public:
- BoolWrapper() {
- clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
- value = true;
- }
- bool value;
- };
-
- void test() {
- // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined.
- if (BoolWrapper().value)
- return;
- }
-}
Modified: cfe/trunk/test/Analysis/method-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/method-call.cpp?rev=163004&r1=163003&r2=163004&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/method-call.cpp (original)
+++ cfe/trunk/test/Analysis/method-call.cpp Fri Aug 31 12:06:49 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -verify %s
void clang_analyzer_eval(bool);
More information about the cfe-commits
mailing list