[cfe-commits] r162430 - in /cfe/trunk: include/clang/Rewrite/RewriteRope.h lib/ARCMigrate/Transforms.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaObjCProperty.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/StaticAnalyzer/Core/SymbolManager.cpp unittests/Tooling/RewriterTestContext.h

Richard Smith richard-llvm at metafoo.co.uk
Wed Aug 22 23:16:53 PDT 2012


Author: rsmith
Date: Thu Aug 23 01:16:52 2012
New Revision: 162430

URL: http://llvm.org/viewvc/llvm-project?rev=162430&view=rev
Log:
Fix undefined behavior: member function calls where 'this' is a null pointer.

Modified:
    cfe/trunk/include/clang/Rewrite/RewriteRope.h
    cfe/trunk/lib/ARCMigrate/Transforms.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp
    cfe/trunk/unittests/Tooling/RewriterTestContext.h

Modified: cfe/trunk/include/clang/Rewrite/RewriteRope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/RewriteRope.h?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/RewriteRope.h (original)
+++ cfe/trunk/include/clang/Rewrite/RewriteRope.h Thu Aug 23 01:16:52 2012
@@ -33,11 +33,11 @@
     char Data[1];  //  Variable sized.
 
     void addRef() {
-      if (this) ++RefCount;
+      ++RefCount;
     }
 
     void dropRef() {
-      if (this && --RefCount == 0)
+      if (--RefCount == 0)
         delete [] (char*)this;
     }
   };
@@ -63,22 +63,27 @@
 
     RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
       : StrData(Str), StartOffs(Start), EndOffs(End) {
-      StrData->addRef();
+      if (StrData)
+        StrData->addRef();
     }
     RopePiece(const RopePiece &RP)
       : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
-      StrData->addRef();
+      if (StrData)
+        StrData->addRef();
     }
 
     ~RopePiece() {
-      StrData->dropRef();
+      if (StrData)
+        StrData->dropRef();
     }
 
     void operator=(const RopePiece &RHS) {
       if (StrData != RHS.StrData) {
-        StrData->dropRef();
+        if (StrData)
+          StrData->dropRef();
         StrData = RHS.StrData;
-        StrData->addRef();
+        if (StrData)
+          StrData->addRef();
       }
       StartOffs = RHS.StartOffs;
       EndOffs = RHS.EndOffs;
@@ -191,7 +196,8 @@
 
   ~RewriteRope() {
     // If we had an allocation buffer, drop our reference to it.
-    AllocBuffer->dropRef();
+    if (AllocBuffer)
+      AllocBuffer->dropRef();
   }
 
   typedef RopePieceBTree::iterator iterator;

Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Thu Aug 23 01:16:52 2012
@@ -59,7 +59,7 @@
       return false; // id/NSObject is not safe for weak.
     if (!AllowOnUnknownClass && !Class->hasDefinition())
       return false; // forward classes are not verifiable, therefore not safe.
-    if (Class->isArcWeakrefUnavailable())
+    if (Class && Class->isArcWeakrefUnavailable())
       return false;
   }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 23 01:16:52 2012
@@ -10438,10 +10438,10 @@
     // If this definition appears within the record, do the checking when
     // the record is complete.
     const FunctionDecl *Primary = MD;
-    if (MD->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
+    if (const FunctionDecl *Pattern = MD->getTemplateInstantiationPattern())
       // Find the uninstantiated declaration that actually had the '= default'
       // on it.
-      MD->getTemplateInstantiationPattern()->isDefined(Primary);
+      Pattern->isDefined(Primary);
 
     if (Primary == Primary->getCanonicalDecl())
       return;
@@ -10966,14 +10966,16 @@
   if (Ctor->isInvalidDecl())
     return;
 
-  const FunctionDecl *FNTarget = 0;
-  CXXConstructorDecl *Target;
-  
-  // We ignore the result here since if we don't have a body, Target will be
-  // null below.
-  (void)Ctor->getTargetConstructor()->hasBody(FNTarget);
-  Target
-= const_cast<CXXConstructorDecl*>(cast_or_null<CXXConstructorDecl>(FNTarget));
+  CXXConstructorDecl *Target = Ctor->getTargetConstructor();
+
+  // Target may not be determinable yet, for instance if this is a dependent
+  // call in an uninstantiated template.
+  if (Target) {
+    const FunctionDecl *FNTarget = 0;
+    (void)Target->hasBody(FNTarget);
+    Target = const_cast<CXXConstructorDecl*>(
+      cast_or_null<CXXConstructorDecl>(FNTarget));
+  }
 
   CXXConstructorDecl *Canonical = Ctor->getCanonicalDecl(),
                      // Avoid dereferencing a null pointer here.
@@ -10997,17 +10999,18 @@
              diag::warn_delegating_ctor_cycle)
         << Ctor;
 
-      // Don't add a note for a function delegating directo to itself.
+      // Don't add a note for a function delegating directly to itself.
       if (TCanonical != Canonical)
         S.Diag(Target->getLocation(), diag::note_it_delegates_to);
 
       CXXConstructorDecl *C = Target;
       while (C->getCanonicalDecl() != Canonical) {
+        const FunctionDecl *FNTarget = 0;
         (void)C->getTargetConstructor()->hasBody(FNTarget);
         assert(FNTarget && "Ctor cycle through bodiless function");
 
-        C
-       = const_cast<CXXConstructorDecl*>(cast<CXXConstructorDecl>(FNTarget));
+        C = const_cast<CXXConstructorDecl*>(
+          cast<CXXConstructorDecl>(FNTarget));
         S.Diag(C->getLocation(), diag::note_which_delegates_to);
       }
     }
@@ -11030,9 +11033,8 @@
   for (DelegatingCtorDeclsType::iterator
          I = DelegatingCtorDecls.begin(ExternalSource),
          E = DelegatingCtorDecls.end();
-       I != E; ++I) {
-   DelegatingCycleHelper(*I, Valid, Invalid, Current, *this);
-  }
+       I != E; ++I)
+    DelegatingCycleHelper(*I, Valid, Invalid, Current, *this);
 
   for (CI = Invalid.begin(), CE = Invalid.end(); CI != CE; ++CI)
     (*CI)->setInvalidDecl();

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Thu Aug 23 01:16:52 2012
@@ -3101,8 +3101,8 @@
       canExprType->isObjCObjectPointerType()) {
     if (const ObjCObjectPointerType *ObjT =
         canExprType->getAs<ObjCObjectPointerType>())
-      if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable())
-        return false;
+      if (const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl())
+        return !ObjI->isArcWeakrefUnavailable();
   }
   return true;
 }

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Thu Aug 23 01:16:52 2012
@@ -886,12 +886,14 @@
           if (lifetime == Qualifiers::OCL_Weak) {
             bool err = false;
             if (const ObjCObjectPointerType *ObjT =
-                PropertyIvarType->getAs<ObjCObjectPointerType>())
-              if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) {
+                PropertyIvarType->getAs<ObjCObjectPointerType>()) {
+              const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl();
+              if (ObjI && ObjI->isArcWeakrefUnavailable()) {
                 Diag(PropertyDiagLoc, diag::err_arc_weak_unavailable_property);
                 Diag(property->getLocation(), diag::note_property_declare);
                 err = true;
               }
+            }
             if (!err && !getLangOpts().ObjCARCWeak) {
               Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime);
               Diag(property->getLocation(), diag::note_property_declare);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Aug 23 01:16:52 2012
@@ -1999,9 +1999,11 @@
     for (unsigned I = 0; I < Depth; ++I)
       TemplateArgLists.addOuterTemplateArguments(0, 0);
 
+    LocalInstantiationScope Scope(*this);
     InstantiatingTemplate Inst(*this, TemplateLoc, Template);
     if (Inst)
       return QualType();
+
     CanonType = SubstType(Pattern->getUnderlyingType(),
                           TemplateArgLists, AliasTemplate->getLocation(),
                           AliasTemplate->getDeclName());

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Aug 23 01:16:52 2012
@@ -570,6 +570,9 @@
     SavedPacks[I] = Deduced[PackIndices[I]];
     Deduced[PackIndices[I]] = TemplateArgument();
 
+    if (!S.CurrentInstantiationScope)
+      continue;
+
     // If the template arugment pack was explicitly specified, add that to
     // the set of deduced arguments.
     const TemplateArgument *ExplicitArgs;
@@ -2601,7 +2604,8 @@
       // explicitly-specified set (C++0x [temp.arg.explicit]p9).
       const TemplateArgument *ExplicitArgs;
       unsigned NumExplicitArgs;
-      if (CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs,
+      if (CurrentInstantiationScope &&
+          CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs,
                                                              &NumExplicitArgs)
           == Param)
         Builder.push_back(TemplateArgument(ExplicitArgs, NumExplicitArgs));

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SymbolManager.cpp Thu Aug 23 01:16:52 2012
@@ -520,7 +520,7 @@
   const StackFrameContext *CurrentContext = LCtx->getCurrentStackFrame();
 
   if (VarContext == CurrentContext) {
-    // If no statemetnt is provided, everything is live.
+    // If no statement is provided, everything is live.
     if (!Loc)
       return true;
 
@@ -548,7 +548,7 @@
     return false;
   }
 
-  return VarContext->isParentOf(CurrentContext);
+  return !VarContext || VarContext->isParentOf(CurrentContext);
 }
 
 SymbolVisitor::~SymbolVisitor() {}

Modified: cfe/trunk/unittests/Tooling/RewriterTestContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RewriterTestContext.h?rev=162430&r1=162429&r2=162430&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/RewriterTestContext.h (original)
+++ cfe/trunk/unittests/Tooling/RewriterTestContext.h Thu Aug 23 01:16:52 2012
@@ -35,7 +35,7 @@
 class RewriterTestContext {
  public:
   RewriterTestContext()
-      : Diagnostics(llvm::IntrusiveRefCntPtr<DiagnosticIDs>()),
+      : Diagnostics(llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs)),
         DiagnosticPrinter(llvm::outs(), DiagnosticOptions()),
         Files((FileSystemOptions())),
         Sources(Diagnostics, Files),





More information about the cfe-commits mailing list