summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Analysis')
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/AnalysisDeclContext.cpp41
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/BodyFarm.cpp57
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/BodyFarm.h2
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/CFG.cpp62
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/CallGraph.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/FormatString.cpp43
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/FormatStringParsing.h8
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp11
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp11
11 files changed, 210 insertions, 41 deletions
diff --git a/contrib/llvm/tools/clang/lib/Analysis/AnalysisDeclContext.cpp b/contrib/llvm/tools/clang/lib/Analysis/AnalysisDeclContext.cpp
index 52c7f26..6bbe8f8 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/AnalysisDeclContext.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/AnalysisDeclContext.cpp
@@ -94,19 +94,25 @@ Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
IsAutosynthesized = false;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Stmt *Body = FD->getBody();
- if (!Body && Manager && Manager->synthesizeBodies()) {
- Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
- if (Body)
+ if (Manager && Manager->synthesizeBodies()) {
+ Stmt *SynthesizedBody =
+ getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
+ if (SynthesizedBody) {
+ Body = SynthesizedBody;
IsAutosynthesized = true;
+ }
}
return Body;
}
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Stmt *Body = MD->getBody();
- if (!Body && Manager && Manager->synthesizeBodies()) {
- Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
- if (Body)
+ if (Manager && Manager->synthesizeBodies()) {
+ Stmt *SynthesizedBody =
+ getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
+ if (SynthesizedBody) {
+ Body = SynthesizedBody;
IsAutosynthesized = true;
+ }
}
return Body;
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
@@ -135,6 +141,10 @@ bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
return Tmp && Body->getLocStart().isValid();
}
+/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
+static bool isSelfDecl(const VarDecl *VD) {
+ return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
+}
const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
@@ -143,7 +153,7 @@ const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
// See if 'self' was captured by the block.
for (const auto &I : BD->captures()) {
const VarDecl *VD = I.getVariable();
- if (VD->getName() == "self")
+ if (isSelfDecl(VD))
return dyn_cast<ImplicitParamDecl>(VD);
}
}
@@ -161,7 +171,7 @@ const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
continue;
VarDecl *VD = LC.getCapturedVar();
- if (VD->getName() == "self")
+ if (isSelfDecl(VD))
return dyn_cast<ImplicitParamDecl>(VD);
}
@@ -317,6 +327,21 @@ AnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent,
BD, ContextData);
}
+bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
+ const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
+ const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
+ if (!ND)
+ return false;
+
+ while (const DeclContext *Parent = ND->getParent()) {
+ if (!isa<NamespaceDecl>(Parent))
+ break;
+ ND = cast<NamespaceDecl>(Parent);
+ }
+
+ return ND->isStdNamespace();
+}
+
LocationContextManager & AnalysisDeclContext::getLocationContextManager() {
assert(Manager &&
"Cannot create LocationContexts without an AnalysisDeclContextManager!");
diff --git a/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.cpp b/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.cpp
index 0990436..d202a04 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.cpp
@@ -239,7 +239,8 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
SourceLocation());
// (5) Create the 'if' statement.
- IfStmt *If = new (C) IfStmt(C, SourceLocation(), nullptr, UO, CS);
+ IfStmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr,
+ UO, CS);
return If;
}
@@ -342,9 +343,8 @@ static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
Stmt *Else = M.makeReturn(RetVal);
/// Construct the If.
- Stmt *If =
- new (C) IfStmt(C, SourceLocation(), nullptr, Comparison, Body,
- SourceLocation(), Else);
+ Stmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr,
+ Comparison, Body, SourceLocation(), Else);
return If;
}
@@ -383,10 +383,49 @@ Stmt *BodyFarm::getBody(const FunctionDecl *D) {
return Val.getValue();
}
+static const ObjCIvarDecl *findBackingIvar(const ObjCPropertyDecl *Prop) {
+ const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
+
+ if (IVar)
+ return IVar;
+
+ // When a readonly property is shadowed in a class extensions with a
+ // a readwrite property, the instance variable belongs to the shadowing
+ // property rather than the shadowed property. If there is no instance
+ // variable on a readonly property, check to see whether the property is
+ // shadowed and if so try to get the instance variable from shadowing
+ // property.
+ if (!Prop->isReadOnly())
+ return nullptr;
+
+ auto *Container = cast<ObjCContainerDecl>(Prop->getDeclContext());
+ const ObjCInterfaceDecl *PrimaryInterface = nullptr;
+ if (auto *InterfaceDecl = dyn_cast<ObjCInterfaceDecl>(Container)) {
+ PrimaryInterface = InterfaceDecl;
+ } else if (auto *CategoryDecl = dyn_cast<ObjCCategoryDecl>(Container)) {
+ PrimaryInterface = CategoryDecl->getClassInterface();
+ } else if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container)) {
+ PrimaryInterface = ImplDecl->getClassInterface();
+ } else {
+ return nullptr;
+ }
+
+ // FindPropertyVisibleInPrimaryClass() looks first in class extensions, so it
+ // is guaranteed to find the shadowing property, if it exists, rather than
+ // the shadowed property.
+ auto *ShadowingProp = PrimaryInterface->FindPropertyVisibleInPrimaryClass(
+ Prop->getIdentifier(), Prop->getQueryKind());
+ if (ShadowingProp && ShadowingProp != Prop) {
+ IVar = ShadowingProp->getPropertyIvarDecl();
+ }
+
+ return IVar;
+}
+
static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
const ObjCPropertyDecl *Prop) {
// First, find the backing ivar.
- const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
+ const ObjCIvarDecl *IVar = findBackingIvar(Prop);
if (!IVar)
return nullptr;
@@ -459,6 +498,14 @@ Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
return nullptr;
// For now, we only synthesize getters.
+ // Synthesizing setters would cause false negatives in the
+ // RetainCountChecker because the method body would bind the parameter
+ // to an instance variable, causing it to escape. This would prevent
+ // warning in the following common scenario:
+ //
+ // id foo = [[NSObject alloc] init];
+ // self.foo = foo; // We should warn that foo leaks here.
+ //
if (D->param_size() != 0)
return nullptr;
diff --git a/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.h b/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.h
index 9137943..edbe996 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.h
+++ b/contrib/llvm/tools/clang/lib/Analysis/BodyFarm.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
+#include "clang/AST/DeclBase.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
@@ -22,7 +23,6 @@
namespace clang {
class ASTContext;
-class Decl;
class FunctionDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl;
diff --git a/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp b/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp
index ed2239f..a67f091 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/CFG.cpp
@@ -1,4 +1,4 @@
- //===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===//
+//===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -825,7 +825,7 @@ private:
// * Variable x is equal to the largest literal.
// * Variable x is greater than largest literal.
bool AlwaysTrue = true, AlwaysFalse = true;
- for (llvm::APSInt Value : Values) {
+ for (const llvm::APSInt &Value : Values) {
TryResult Res1, Res2;
Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
Res2 = analyzeLogicOperatorCondition(BO2, Value, L2);
@@ -1945,7 +1945,8 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) {
addLocalScopeForStmt(C);
}
if (!C->body_empty() && !isa<ReturnStmt>(*C->body_rbegin())) {
- // If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt
+ // If the body ends with a ReturnStmt, the dtors will be added in
+ // VisitReturnStmt.
addAutomaticObjDtors(ScopePos, scopeBeginPos, C);
}
@@ -2168,6 +2169,13 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
// won't be restored when traversing AST.
SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
+ // Create local scope for C++17 if init-stmt if one exists.
+ if (Stmt *Init = I->getInit()) {
+ LocalScope::const_iterator BeginScopePos = ScopePos;
+ addLocalScopeForStmt(Init);
+ addAutomaticObjDtors(ScopePos, BeginScopePos, I);
+ }
+
// Create local scope for possible condition variable.
// Store scope position. Add implicit destructor.
if (VarDecl *VD = I->getConditionVariable()) {
@@ -2268,13 +2276,19 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
// blocks will be pointed to be "Block".
CFGBlock *LastBlock = addStmt(I->getCond());
- // Finally, if the IfStmt contains a condition variable, add it and its
+ // If the IfStmt contains a condition variable, add it and its
// initializer to the CFG.
if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) {
autoCreateBlock();
LastBlock = addStmt(const_cast<DeclStmt *>(DS));
}
+ // Finally, if the IfStmt contains a C++17 init-stmt, add it to the CFG.
+ if (Stmt *Init = I->getInit()) {
+ autoCreateBlock();
+ LastBlock = addStmt(Init);
+ }
+
return LastBlock;
}
@@ -3059,6 +3073,13 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
// won't be restored when traversing AST.
SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
+ // Create local scope for C++17 switch init-stmt if one exists.
+ if (Stmt *Init = Terminator->getInit()) {
+ LocalScope::const_iterator BeginScopePos = ScopePos;
+ addLocalScopeForStmt(Init);
+ addAutomaticObjDtors(ScopePos, BeginScopePos, Terminator);
+ }
+
// Create local scope for possible condition variable.
// Store scope position. Add implicit destructor.
if (VarDecl *VD = Terminator->getConditionVariable()) {
@@ -3138,7 +3159,7 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
Block = SwitchTerminatedBlock;
CFGBlock *LastBlock = addStmt(Terminator->getCond());
- // Finally, if the SwitchStmt contains a condition variable, add both the
+ // If the SwitchStmt contains a condition variable, add both the
// SwitchStmt and the condition variable initialization to the CFG.
if (VarDecl *VD = Terminator->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
@@ -3148,6 +3169,12 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
}
}
+ // Finally, if the SwitchStmt contains a C++17 init-stmt, add it to the CFG.
+ if (Stmt *Init = Terminator->getInit()) {
+ autoCreateBlock();
+ LastBlock = addStmt(Init);
+ }
+
return LastBlock;
}
@@ -3397,8 +3424,10 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
// Create local scopes and destructors for range, begin and end variables.
if (Stmt *Range = S->getRangeStmt())
addLocalScopeForStmt(Range);
- if (Stmt *BeginEnd = S->getBeginEndStmt())
- addLocalScopeForStmt(BeginEnd);
+ if (Stmt *Begin = S->getBeginStmt())
+ addLocalScopeForStmt(Begin);
+ if (Stmt *End = S->getEndStmt())
+ addLocalScopeForStmt(End);
addAutomaticObjDtors(ScopePos, save_scope_pos.get(), S);
LocalScope::const_iterator ContinueScopePos = ScopePos;
@@ -3455,6 +3484,8 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
// continue statements.
Block = nullptr;
Succ = addStmt(S->getInc());
+ if (badCFG)
+ return nullptr;
ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos);
// The starting block for the loop increment is the block that should
@@ -3489,7 +3520,8 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
// Add the initialization statements.
Block = createBlock();
- addStmt(S->getBeginEndStmt());
+ addStmt(S->getBeginStmt());
+ addStmt(S->getEndStmt());
return addStmt(S->getRangeStmt());
}
@@ -3870,7 +3902,17 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const {
case CFGElement::AutomaticObjectDtor: {
const VarDecl *var = castAs<CFGAutomaticObjDtor>().getVarDecl();
QualType ty = var->getType();
- ty = ty.getNonReferenceType();
+
+ // FIXME: See CFGBuilder::addLocalScopeForVarDecl.
+ //
+ // Lifetime-extending constructs are handled here. This works for a single
+ // temporary in an initializer expression.
+ if (ty->isReferenceType()) {
+ if (const Expr *Init = var->getInit()) {
+ ty = getReferenceInitTemporaryType(astContext, Init);
+ }
+ }
+
while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) {
ty = arrayType->getElementType();
}
@@ -4514,7 +4556,7 @@ void CFGBlock::dump(const CFG* cfg, const LangOptions &LO,
print(llvm::errs(), cfg, LO, ShowColors);
}
-void CFGBlock::dump() const {
+LLVM_DUMP_METHOD void CFGBlock::dump() const {
dump(getParent(), LangOptions(), false);
}
diff --git a/contrib/llvm/tools/clang/lib/Analysis/CallGraph.cpp b/contrib/llvm/tools/clang/lib/Analysis/CallGraph.cpp
index d0660346..9d522fe 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/CallGraph.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/CallGraph.cpp
@@ -188,7 +188,7 @@ void CallGraph::print(raw_ostream &OS) const {
OS.flush();
}
-void CallGraph::dump() const {
+LLVM_DUMP_METHOD void CallGraph::dump() const {
print(llvm::errs());
}
@@ -202,7 +202,7 @@ void CallGraphNode::print(raw_ostream &os) const {
os << "< >";
}
-void CallGraphNode::dump() const {
+LLVM_DUMP_METHOD void CallGraphNode::dump() const {
print(llvm::errs());
}
diff --git a/contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp b/contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp
index 9df2392..47bef1b 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp
@@ -466,9 +466,15 @@ class ConsumedStmtVisitor : public ConstStmtVisitor<ConsumedStmtVisitor> {
MapType PropagationMap;
InfoEntry findInfo(const Expr *E) {
+ if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
+ if (!Cleanups->cleanupsHaveSideEffects())
+ E = Cleanups->getSubExpr();
return PropagationMap.find(E->IgnoreParens());
}
ConstInfoEntry findInfo(const Expr *E) const {
+ if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
+ if (!Cleanups->cleanupsHaveSideEffects())
+ E = Cleanups->getSubExpr();
return PropagationMap.find(E->IgnoreParens());
}
void insertInfo(const Expr *E, const PropagationInfo &PI) {
@@ -1356,7 +1362,7 @@ void ConsumedAnalyzer::run(AnalysisDeclContext &AC) {
ConsumedStmtVisitor Visitor(AC, *this, CurrStates.get());
// Add all trackable parameters to the state map.
- for (const auto *PI : D->params())
+ for (const auto *PI : D->parameters())
Visitor.VisitParmVarDecl(PI);
// Visit all of the function's basic blocks.
diff --git a/contrib/llvm/tools/clang/lib/Analysis/FormatString.cpp b/contrib/llvm/tools/clang/lib/Analysis/FormatString.cpp
index 0948bc0..83d08b5 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/FormatString.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/FormatString.cpp
@@ -15,6 +15,7 @@
#include "FormatStringParsing.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/Support/ConvertUTF.h"
using clang::analyze_format_string::ArgType;
using clang::analyze_format_string::FormatStringHandler;
@@ -190,13 +191,21 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
return false;
case 'h':
++I;
- lmKind = (I != E && *I == 'h') ? (++I, LengthModifier::AsChar)
- : LengthModifier::AsShort;
+ if (I != E && *I == 'h') {
+ ++I;
+ lmKind = LengthModifier::AsChar;
+ } else {
+ lmKind = LengthModifier::AsShort;
+ }
break;
case 'l':
++I;
- lmKind = (I != E && *I == 'l') ? (++I, LengthModifier::AsLongLong)
- : LengthModifier::AsLong;
+ if (I != E && *I == 'l') {
+ ++I;
+ lmKind = LengthModifier::AsLongLong;
+ } else {
+ lmKind = LengthModifier::AsLong;
+ }
break;
case 'j': lmKind = LengthModifier::AsIntMax; ++I; break;
case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
@@ -252,6 +261,28 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
return true;
}
+bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
+ const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
+ if (SpecifierBegin + 1 >= FmtStrEnd)
+ return false;
+
+ const UTF8 *SB = reinterpret_cast<const UTF8 *>(SpecifierBegin + 1);
+ const UTF8 *SE = reinterpret_cast<const UTF8 *>(FmtStrEnd);
+ const char FirstByte = *SB;
+
+ // If the invalid specifier is a multibyte UTF-8 string, return the
+ // total length accordingly so that the conversion specifier can be
+ // properly updated to reflect a complete UTF-8 specifier.
+ unsigned NumBytes = getNumBytesForUTF8(FirstByte);
+ if (NumBytes == 1)
+ return false;
+ if (SB + NumBytes > SE)
+ return false;
+
+ Len = NumBytes + 1;
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Methods on ArgType.
//===----------------------------------------------------------------------===//
@@ -663,7 +694,7 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
return true;
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
- return Target.getTriple().isOSFreeBSD();
+ return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
default:
return false;
}
@@ -696,7 +727,7 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
return true;
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
- return Target.getTriple().isOSFreeBSD();
+ return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
default:
return false;
}
diff --git a/contrib/llvm/tools/clang/lib/Analysis/FormatStringParsing.h b/contrib/llvm/tools/clang/lib/Analysis/FormatStringParsing.h
index e165296..8463fce 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/FormatStringParsing.h
+++ b/contrib/llvm/tools/clang/lib/Analysis/FormatStringParsing.h
@@ -46,7 +46,13 @@ bool ParseArgPosition(FormatStringHandler &H,
/// FormatSpecifier& argument, and false otherwise.
bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E,
const LangOptions &LO, bool IsScanf = false);
-
+
+/// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8
+/// string; check that it won't go further than \p FmtStrEnd and write
+/// up the total size in \p Len.
+bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin,
+ const char *FmtStrEnd, unsigned &Len);
+
template <typename T> class SpecifierResult {
T FS;
const char *Start;
diff --git a/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp b/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp
index f0976bc..ac6cef9 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp
@@ -312,8 +312,13 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
argIndex++;
if (k == ConversionSpecifier::InvalidSpecifier) {
+ unsigned Len = I - Start;
+ if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
+ CS.setEndScanList(Start + Len);
+ FS.setConversionSpecifier(CS);
+ }
// Assume the conversion takes one argument.
- return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start);
+ return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
}
return PrintfSpecifierResult(Start, FS);
}
@@ -611,9 +616,13 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
case BuiltinType::UInt128:
case BuiltinType::Int128:
case BuiltinType::Half:
+ case BuiltinType::Float128:
// Various types which are non-trivial to correct.
return false;
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
+ case BuiltinType::Id:
+#include "clang/Basic/OpenCLImageTypes.def"
#define SIGNED_TYPE(Id, SingletonId)
#define UNSIGNED_TYPE(Id, SingletonId)
#define FLOATING_TYPE(Id, SingletonId)
diff --git a/contrib/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp b/contrib/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp
index 5b917a7..614f676 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/PseudoConstantAnalysis.cpp
@@ -22,9 +22,7 @@
using namespace clang;
-// The number of ValueDecls we want to keep track of by default (per-function)
-#define VARDECL_SET_SIZE 256
-typedef llvm::SmallPtrSet<const VarDecl*, VARDECL_SET_SIZE> VarDeclSet;
+typedef llvm::SmallPtrSet<const VarDecl*, 32> VarDeclSet;
PseudoConstantAnalysis::PseudoConstantAnalysis(const Stmt *DeclBody) :
DeclBody(DeclBody), Analyzed(false) {
diff --git a/contrib/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp b/contrib/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp
index d484d8e..82b0388 100644
--- a/contrib/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp
+++ b/contrib/llvm/tools/clang/lib/Analysis/ScanfFormatString.cpp
@@ -79,7 +79,7 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H,
unsigned &argIndex,
const LangOptions &LO,
const TargetInfo &Target) {
-
+ using namespace clang::analyze_format_string;
using namespace clang::analyze_scanf;
const char *I = Beg;
const char *Start = nullptr;
@@ -210,10 +210,15 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H,
// FIXME: '%' and '*' doesn't make sense. Issue a warning.
// FIXME: 'ConsumedSoFar' and '*' doesn't make sense.
-
+
if (k == ScanfConversionSpecifier::InvalidSpecifier) {
+ unsigned Len = I - Beg;
+ if (ParseUTF8InvalidSpecifier(Beg, E, Len)) {
+ CS.setEndScanList(Beg + Len);
+ FS.setConversionSpecifier(CS);
+ }
// Assume the conversion takes one argument.
- return !H.HandleInvalidScanfConversionSpecifier(FS, Beg, I - Beg);
+ return !H.HandleInvalidScanfConversionSpecifier(FS, Beg, Len);
}
return ScanfSpecifierResult(Start, FS);
}
OpenPOWER on IntegriCloud