Fix undefined behavior: member function calls where 'this' is a null pointer.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162430 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index f01dfa9..805a67d 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -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;
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2d3f2c0..ce37eea 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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();
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 0aabf8b..7c19a13 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -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;
}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 84b6096..98c1bb2 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -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);
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 98497cb..229d8c0 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -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());
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 9500ec3..48ad0bf 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -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));
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp
index 440ddff..c21df4c 100644
--- a/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -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() {}