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