]> granicus.if.org Git - clang/commitdiff
Fix overzealous assertion in GRExprEngine::VisitLValue(). A
authorTed Kremenek <kremenek@apple.com>
Sat, 9 Jan 2010 22:58:54 +0000 (22:58 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 9 Jan 2010 22:58:54 +0000 (22:58 +0000)
CallExpr/ObjCMessageExpr can be visited in an "lvalue" context if it
returns a struct temporary.  Currently the analyzer doesn't reason
about struct temporary returned by function calls, but we shouldn't
crash here either.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93081 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/GRExprEngine.cpp
test/Analysis/misc-ps-region-store.m

index ed3dc8abac1816f6b7c957782d67000a4b994371..b9a0ddc623c33ebb4164ea27bf6285a7922f2ed4 100644 (file)
@@ -47,10 +47,9 @@ static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
 }
 
 
-static bool CalleeReturnsReference(const CallExpr *CE) { 
+static QualType GetCalleeReturnType(const CallExpr *CE) { 
   const Expr *Callee = CE->getCallee();
   QualType T = Callee->getType();
-  
   if (const PointerType *PT = T->getAs<PointerType>()) {
     const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>();
     T = FT->getResultType();
@@ -58,16 +57,35 @@ static bool CalleeReturnsReference(const CallExpr *CE) {
   else {
     const BlockPointerType *BT = T->getAs<BlockPointerType>();
     T = BT->getPointeeType()->getAs<FunctionType>()->getResultType();
-  }  
-  return T->isReferenceType();
+  }
+  return T;
+}
+
+static bool CalleeReturnsReference(const CallExpr *CE) { 
+  return (bool) GetCalleeReturnType(CE)->getAs<ReferenceType>();
 }
 
 static bool ReceiverReturnsReference(const ObjCMessageExpr *ME) {
   const ObjCMethodDecl *MD = ME->getMethodDecl();
   if (!MD)
     return false;
-  return MD->getResultType()->isReferenceType();
+  return MD->getResultType()->getAs<ReferenceType>();
+}
+
+#ifndef NDEBUG
+static bool ReceiverReturnsReferenceOrRecord(const ObjCMessageExpr *ME) {
+  const ObjCMethodDecl *MD = ME->getMethodDecl();
+  if (!MD)
+    return false;
+  QualType T = MD->getResultType();
+  return T->getAs<RecordType>() || T->getAs<ReferenceType>();
+}
+
+static bool CalleeReturnsReferenceOrRecord(const CallExpr *CE) {
+  QualType T = GetCalleeReturnType(CE);
+  return T->getAs<ReferenceType>() || T->getAs<RecordType>();
 }
+#endif
 
 //===----------------------------------------------------------------------===//
 // Batch auditor.  DEPRECATED.
@@ -825,7 +843,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
     case Stmt::CallExprClass:
     case Stmt::CXXOperatorCallExprClass: {
       CallExpr *C = cast<CallExpr>(Ex);
-      assert(CalleeReturnsReference(C));
+      assert(CalleeReturnsReferenceOrRecord(C));
       VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, true);      
       break;
     }
@@ -856,7 +874,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
       
     case Stmt::ObjCMessageExprClass: {
       ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
-      assert(ReceiverReturnsReference(ME));
+      assert(ReceiverReturnsReferenceOrRecord(ME));
       VisitObjCMessageExpr(ME, Pred, Dst, true); 
       return;
     }
index 06114c2ab021001c70c59b67f04c3158950b75df..df423efeaebacba6bc473fa7fb165d48805990e2 100644 (file)
@@ -684,3 +684,29 @@ void pr4358(struct pr4358 *pnt) {
   }
   pr4358_aux(uninit); // no-warning
 }
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7526777>
+// Test handling fields of values returned from function calls or
+// message expressions.
+//===----------------------------------------------------------------------===//
+
+typedef struct testReturn_rdar_7526777 {
+  int x;
+  int y;
+} testReturn_rdar_7526777;
+
+@interface TestReturnStruct_rdar_7526777
+- (testReturn_rdar_7526777) foo;
+@end
+
+int test_return_struct(TestReturnStruct_rdar_7526777 *x) {
+  return [x foo].x;
+}
+
+testReturn_rdar_7526777 test_return_struct_2_aux_rdar_7526777();
+
+int test_return_struct_2_rdar_7526777() {
+  return test_return_struct_2_aux_rdar_7526777().x;
+}
+