diff options
author | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
commit | 06210ae42d418d50d8d9365d5c9419308ae9e7ee (patch) | |
tree | ab60b4cdd6e430dda1f292a46a77ddb744723f31 /contrib/llvm/tools/clang/lib/Analysis | |
parent | 2dd166267f53df1c3748b4325d294b9b839de74b (diff) | |
download | FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.zip FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.tar.gz |
MFC r309124:
Upgrade our copies of clang, llvm, lldb, compiler-rt and libc++ to 3.9.0
release, and add lld 3.9.0. Also completely revamp the build system for
clang, llvm, lldb and their related tools.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld are available here:
<http://llvm.org/releases/3.9.0/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Bryan Drewery, Andrew Turner, Antoine Brodin and Jan
Beich for their help.
Relnotes: yes
MFC r309147:
Pull in r282174 from upstream llvm trunk (by Krzysztof Parzyszek):
[PPC] Set SP after loading data from stack frame, if no red zone is
present
Follow-up to r280705: Make sure that the SP is only restored after
all data is loaded from the stack frame, if there is no red zone.
This completes the fix for
https://llvm.org/bugs/show_bug.cgi?id=26519.
Differential Revision: https://reviews.llvm.org/D24466
Reported by: Mark Millard
PR: 214433
MFC r309149:
Pull in r283060 from upstream llvm trunk (by Hal Finkel):
[PowerPC] Refactor soft-float support, and enable PPC64 soft float
This change enables soft-float for PowerPC64, and also makes
soft-float disable all vector instruction sets for both 32-bit and
64-bit modes. This latter part is necessary because the PPC backend
canonicalizes many Altivec vector types to floating-point types, and
so soft-float breaks scalarization support for many operations. Both
for embedded targets and for operating-system kernels desiring
soft-float support, it seems reasonable that disabling hardware
floating-point also disables vector instructions (embedded targets
without hardware floating point support are unlikely to have Altivec,
etc. and operating system kernels desiring not to use floating-point
registers to lower syscall cost are unlikely to want to use vector
registers either). If someone needs this to work, we'll need to
change the fact that we promote many Altivec operations to act on
v4f32. To make it possible to disable Altivec when soft-float is
enabled, hardware floating-point support needs to be expressed as a
positive feature, like the others, and not a negative feature,
because target features cannot have dependencies on the disabling of
some other feature. So +soft-float has now become -hard-float.
Fixes PR26970.
Pull in r283061 from upstream clang trunk (by Hal Finkel):
[PowerPC] Enable soft-float for PPC64, and +soft-float -> -hard-float
Enable soft-float support on PPC64, as the backend now supports it.
Also, the backend now uses -hard-float instead of +soft-float, so set
the target features accordingly.
Fixes PR26970.
Reported by: Mark Millard
PR: 214433
MFC r309212:
Add a few missed clang 3.9.0 files to OptionalObsoleteFiles.
MFC r309262:
Fix packaging for clang, lldb and lld 3.9.0
During the upgrade of clang/llvm etc to 3.9.0 in r309124, the PACKAGE
directive in the usr.bin/clang/*.mk files got dropped accidentally.
Restore it, with a few minor changes and additions:
* Correct license in clang.ucl to NCSA
* Add PACKAGE=clang for clang and most of the "ll" tools
* Put lldb in its own package
* Put lld in its own package
Reviewed by: gjb, jmallett
Differential Revision: https://reviews.freebsd.org/D8666
MFC r309656:
During the bootstrap phase, when building the minimal llvm library on
PowerPC, add lib/Support/Atomic.cpp. This is needed because upstream
llvm revision r271821 disabled the use of std::call_once, which causes
some fallback functions from Atomic.cpp to be used instead.
Reported by: Mark Millard
PR: 214902
MFC r309835:
Tentatively apply https://reviews.llvm.org/D18730 to work around gcc PR
70528 (bogus error: constructor required before non-static data member).
This should fix buildworld with the external gcc package.
Reported by: https://jenkins.freebsd.org/job/FreeBSD_HEAD_amd64_gcc/
MFC r310194:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
3.9.1 release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/3.9.1/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Analysis')
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); } |