r191599 - [analyzer] Make inlining decisions based on the callee being variadic.
Jordan Rose
jordan_rose at apple.com
Fri Sep 27 19:04:20 PDT 2013
Author: jrose
Date: Fri Sep 27 21:04:19 2013
New Revision: 191599
URL: http://llvm.org/viewvc/llvm-project?rev=191599&view=rev
Log:
[analyzer] Make inlining decisions based on the callee being variadic.
...rather than trying to figure it out from the call site, and having
people complain that we guessed wrong and that a prototype-less call is
the same as a variadic call on their system. More importantly, fix a
crash when there's no decl at the call site (though we could have just
returned a default value).
<rdar://problem/15037033>
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/test/Analysis/inlining/InlineObjCClassMethod.m
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=191599&r1=191598&r2=191599&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Fri Sep 27 21:04:19 2013
@@ -228,11 +228,6 @@ public:
return false;
}
- /// \brief Returns true if this is a call to a variadic function or method.
- virtual bool isVariadic() const {
- return false;
- }
-
/// \brief Returns a source range for the entire call, suitable for
/// outputting in diagnostics.
virtual SourceRange getSourceRange() const {
@@ -341,6 +336,11 @@ public:
/// This will return a null QualType if the result type cannot be determined.
static QualType getDeclaredResultType(const Decl *D);
+ /// \brief Returns true if the given decl is known to be variadic.
+ ///
+ /// \p D must not be null.
+ static bool isVariadic(const Decl *D);
+
// Iterator access to formal parameters and their types.
private:
typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
@@ -417,10 +417,6 @@ public:
return RuntimeDefinition();
}
- virtual bool isVariadic() const {
- return getDecl()->isVariadic();
- }
-
virtual bool argumentsMayEscape() const;
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
@@ -521,10 +517,6 @@ public:
return RuntimeDefinition(getBlockDecl());
}
- virtual bool isVariadic() const {
- return getBlockDecl()->isVariadic();
- }
-
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const;
@@ -843,9 +835,6 @@ public:
virtual const Expr *getArgExpr(unsigned Index) const {
return getOriginExpr()->getArg(Index);
}
- virtual bool isVariadic() const {
- return getDecl()->isVariadic();
- }
bool isInstanceMessage() const {
return getOriginExpr()->isInstanceMessage();
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=191599&r1=191598&r2=191599&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Fri Sep 27 21:04:19 2013
@@ -264,7 +264,20 @@ QualType CallEvent::getDeclaredResultTyp
return QualType();
}
- return QualType();
+ llvm_unreachable("unknown callable kind");
+}
+
+bool CallEvent::isVariadic(const Decl *D) {
+ assert(D);
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ return FD->isVariadic();
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ return MD->isVariadic();
+ if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
+ return BD->isVariadic();
+
+ llvm_unreachable("unknown callable kind");
}
static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=191599&r1=191598&r2=191599&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Fri Sep 27 21:04:19 2013
@@ -740,10 +740,10 @@ static bool isCXXSharedPtrDtor(const Fun
/// This checks static properties of the function, such as its signature and
/// CFG, to determine whether the analyzer should ever consider inlining it,
/// in any context.
-static bool mayInlineDecl(const CallEvent &Call, AnalysisDeclContext *CalleeADC,
+static bool mayInlineDecl(AnalysisDeclContext *CalleeADC,
AnalyzerOptions &Opts) {
// FIXME: Do not inline variadic calls.
- if (Call.isVariadic())
+ if (CallEvent::isVariadic(CalleeADC->getDecl()))
return false;
// Check certain C++-related inlining policies.
@@ -833,7 +833,7 @@ bool ExprEngine::shouldInlineCall(const
} else {
// We haven't actually checked the static properties of this function yet.
// Do that now, and record our decision in the function summaries.
- if (mayInlineDecl(Call, CalleeADC, Opts)) {
+ if (mayInlineDecl(CalleeADC, Opts)) {
Engine.FunctionSummaries->markMayInline(D);
} else {
Engine.FunctionSummaries->markShouldNotInline(D);
Modified: cfe/trunk/test/Analysis/inlining/InlineObjCClassMethod.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/InlineObjCClassMethod.m?rev=191599&r1=191598&r2=191599&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/InlineObjCClassMethod.m (original)
+++ cfe/trunk/test/Analysis/inlining/InlineObjCClassMethod.m Fri Sep 27 21:04:19 2013
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+
+void clang_analyzer_checkInlined(int);
// Test inlining of ObjC class methods.
@@ -209,3 +211,26 @@ int checkSelfUsedInparentClassMethod() {
return 5/[SelfUsedInParentChild fooA];
}
+
+ at interface Rdar15037033 : NSObject
+ at end
+
+void rdar15037033() {
+ [Rdar15037033 forwardDeclaredMethod]; // expected-warning {{class method '+forwardDeclaredMethod' not found}}
+ [Rdar15037033 forwardDeclaredVariadicMethod:1, 2, 3, 0]; // expected-warning {{class method '+forwardDeclaredVariadicMethod:' not found}}
+}
+
+ at implementation Rdar15037033
+
++ (void)forwardDeclaredMethod {
+ clang_analyzer_checkInlined(1); // expected-warning{{TRUE}}
+}
+
++ (void)forwardDeclaredVariadicMethod:(int)x, ... {
+ clang_analyzer_checkInlined(0); // no-warning
+}
+
+ at end
+
+
+
More information about the cfe-commits
mailing list