summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2016-02-21 13:52:32 +0000
committerdim <dim@FreeBSD.org>2016-02-21 13:52:32 +0000
commit733d6099b5ea26022f44be8841b04ed63b6fc47b (patch)
treebd18d1c977939c5f886a223455028f9784d044ac
parent618f0150d38ec96afd49cb3e914990807f8ac5a6 (diff)
downloadFreeBSD-src-733d6099b5ea26022f44be8841b04ed63b6fc47b.zip
FreeBSD-src-733d6099b5ea26022f44be8841b04ed63b6fc47b.tar.gz
Vendor import of clang release_38 branch r261369:
https://llvm.org/svn/llvm-project/cfe/branches/release_38@261369
-rw-r--r--docs/ReleaseNotes.rst54
-rw-r--r--lib/Basic/Targets.cpp4
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp93
-rw-r--r--lib/CodeGen/TargetInfo.cpp15
-rw-r--r--lib/Driver/ToolChains.cpp16
-rw-r--r--lib/Driver/ToolChains.h2
-rw-r--r--lib/Format/ContinuationIndenter.cpp2
-rw-r--r--lib/Sema/SemaOpenMP.cpp166
-rw-r--r--test/CodeGen/arm-vfp-asm-constraint.c36
-rw-r--r--test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp13
-rw-r--r--test/Driver/freebsd.cpp11
-rw-r--r--test/OpenMP/for_ast_print.cpp12
-rw-r--r--test/OpenMP/for_lastprivate_codegen.cpp15
-rw-r--r--test/OpenMP/parallel_messages.cpp5
-rw-r--r--unittests/Format/FormatTest.cpp3
15 files changed, 286 insertions, 161 deletions
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 8c3f46c..18015f8 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -39,12 +39,16 @@ Major New Features
- Feature1...
Improvements to Clang's diagnostics
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+-----------------------------------
Clang's diagnostics are constantly being improved to catch more issues,
explain them more clearly, and provide more accurate source information
about them. The improvements since the 3.7 release include:
+- ``-Wmicrosoft`` has been split into many targeted flags, so that projects can
+ choose to enable only a subset of these warnings. ``-Wno-microsoft`` still
+ disables all these warnings, and ``-Wmicrosoft`` still enables them all.
+
- ...
New Compiler Flags
@@ -140,7 +144,51 @@ Objective-C Language Changes in Clang
OpenCL C Language Changes in Clang
----------------------------------
-...
+Several OpenCL 2.0 features have been added, including:
+
+- Command-line option ``-std=CL2.0``.
+
+- Generic address space (``__generic``) along with new conversion rules
+ between different address spaces and default address space deduction.
+
+- Support for program scope variables with ``__global`` address space.
+
+- Pipe specifier was added (although no pipe functions are supported yet).
+
+- Atomic types: ``atomic_int``, ``atomic_uint``, ``atomic_long``,
+ ``atomic_ulong``, ``atomic_float``, ``atomic_double``, ``atomic_flag``,
+ ``atomic_intptr_t``, ``atomic_uintptr_t``, ``atomic_size_t``,
+ ``atomic_ptrdiff_t`` and their usage with C11 style builtin functions.
+
+- Image types: ``image2d_depth_t``, ``image2d_array_depth_t``,
+ ``image2d_msaa_t``, ``image2d_array_msaa_t``, ``image2d_msaa_depth_t``,
+ ``image2d_array_msaa_depth_t``.
+
+- Other types (for pipes and device side enqueue): ``clk_event_t``,
+ ``queue_t``, ``ndrange_t``, ``reserve_id_t``.
+
+Several additional features/bugfixes have been added to the previous standards:
+
+- A set of floating point arithmetic relaxation flags: ``-cl-no-signed-zeros``,
+ ``-cl-unsafe-math-optimizations``, ``-cl-finite-math-only``,
+ ``-cl-fast-relaxed-math``.
+
+- Added ``^^`` to the list of reserved operations.
+
+- Improved vector support and diagnostics.
+
+- Improved diagnostics for function pointers.
+
+CUDA Support in Clang
+---------------------
+Clang has experimental support for end-to-end CUDA compilation now:
+
+- The driver now detects CUDA installation, creates host and device compilation
+ pipelines, links device-side code with appropriate CUDA bitcode and produces
+ single object file with host and GPU code.
+
+- Implemented target attribute-based function overloading which allows clang to
+ compile CUDA sources without splitting them into separate host/device TUs.
Internal API Changes
--------------------
@@ -220,7 +268,7 @@ Several new checks were added:
``-enable-checker optin.performance.Padding``.
- The checks to detect misuse of ``_Nonnull`` type qualifiers as well as checks
to detect misuse of Objective-C generics were added.
-- The analyzer now has opt in checks to detect localization errors in Coca
+- The analyzer now has opt in checks to detect localization errors in Cocoa
applications. The checks warn about uses of non-localized ``NSStrings``
passed to UI methods expecting localized strings and on ``NSLocalizedString``
macros that are missing the comment argument. These can be enabled by passing
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 4f0b124..af8aea0 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -4915,8 +4915,8 @@ public:
default: break;
case 'l': // r0-r7
case 'h': // r8-r15
- case 'w': // VFP Floating point register single precision
- case 'P': // VFP Floating point register double precision
+ case 't': // VFP Floating point register single precision
+ case 'w': // VFP Floating point register double precision
Info.setAllowsRegister();
return true;
case 'I':
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 59821a8..d0ee891 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -585,71 +585,48 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
EmitBlock(ThenBB);
}
llvm::DenseMap<const Decl *, const Expr *> LoopCountersAndUpdates;
- const Expr *LastIterVal = nullptr;
- const Expr *IVExpr = nullptr;
- const Expr *IncExpr = nullptr;
if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
- if (isOpenMPWorksharingDirective(D.getDirectiveKind())) {
- LastIterVal = cast<VarDecl>(cast<DeclRefExpr>(
- LoopDirective->getUpperBoundVariable())
- ->getDecl())
- ->getAnyInitializer();
- IVExpr = LoopDirective->getIterationVariable();
- IncExpr = LoopDirective->getInc();
- auto IUpdate = LoopDirective->updates().begin();
- for (auto *E : LoopDirective->counters()) {
- auto *D = cast<DeclRefExpr>(E)->getDecl()->getCanonicalDecl();
- LoopCountersAndUpdates[D] = *IUpdate;
- ++IUpdate;
- }
+ auto IC = LoopDirective->counters().begin();
+ for (auto F : LoopDirective->finals()) {
+ auto *D = cast<DeclRefExpr>(*IC)->getDecl()->getCanonicalDecl();
+ LoopCountersAndUpdates[D] = F;
+ ++IC;
}
}
- {
- llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
- bool FirstLCV = true;
- for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
- auto IRef = C->varlist_begin();
- auto ISrcRef = C->source_exprs().begin();
- auto IDestRef = C->destination_exprs().begin();
- for (auto *AssignOp : C->assignment_ops()) {
- auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
- QualType Type = PrivateVD->getType();
- auto *CanonicalVD = PrivateVD->getCanonicalDecl();
- if (AlreadyEmittedVars.insert(CanonicalVD).second) {
- // If lastprivate variable is a loop control variable for loop-based
- // directive, update its value before copyin back to original
- // variable.
- if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) {
- if (FirstLCV && LastIterVal) {
- EmitAnyExprToMem(LastIterVal, EmitLValue(IVExpr).getAddress(),
- IVExpr->getType().getQualifiers(),
- /*IsInitializer=*/false);
- EmitIgnoredExpr(IncExpr);
- FirstLCV = false;
- }
- EmitIgnoredExpr(UpExpr);
- }
- auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
- auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
- // Get the address of the original variable.
- Address OriginalAddr = GetAddrOfLocalVar(DestVD);
- // Get the address of the private variable.
- Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
- if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>())
- PrivateAddr =
+ llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
+ for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
+ auto IRef = C->varlist_begin();
+ auto ISrcRef = C->source_exprs().begin();
+ auto IDestRef = C->destination_exprs().begin();
+ for (auto *AssignOp : C->assignment_ops()) {
+ auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
+ QualType Type = PrivateVD->getType();
+ auto *CanonicalVD = PrivateVD->getCanonicalDecl();
+ if (AlreadyEmittedVars.insert(CanonicalVD).second) {
+ // If lastprivate variable is a loop control variable for loop-based
+ // directive, update its value before copyin back to original
+ // variable.
+ if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
+ EmitIgnoredExpr(UpExpr);
+ auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
+ auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
+ // Get the address of the original variable.
+ Address OriginalAddr = GetAddrOfLocalVar(DestVD);
+ // Get the address of the private variable.
+ Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
+ if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>())
+ PrivateAddr =
Address(Builder.CreateLoad(PrivateAddr),
getNaturalTypeAlignment(RefTy->getPointeeType()));
- EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
- }
- ++IRef;
- ++ISrcRef;
- ++IDestRef;
+ EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
}
+ ++IRef;
+ ++ISrcRef;
+ ++IDestRef;
}
}
- if (IsLastIterCond) {
+ if (IsLastIterCond)
EmitBlock(DoneBB, /*IsFinished=*/true);
- }
}
void CodeGenFunction::EmitOMPReductionClauseInit(
@@ -919,10 +896,6 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
// The end (updates/cleanups).
EmitBlock(Continue.getBlock());
BreakContinueStack.pop_back();
- // TODO: Update lastprivates if the SeparateIter flag is true.
- // This will be implemented in a follow-up OMPLastprivateClause patch, but
- // result should be still correct without it, as we do not make these
- // variables private yet.
}
void CodeGenFunction::EmitOMPInnerLoop(
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 4566fdb..cdb325f 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -4868,9 +4868,6 @@ public:
};
class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
- void addStackProbeSizeTargetAttribute(const Decl *D, llvm::GlobalValue *GV,
- CodeGen::CodeGenModule &CGM) const;
-
public:
WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K)
: ARMTargetCodeGenInfo(CGT, K) {}
@@ -4879,18 +4876,6 @@ public:
CodeGen::CodeGenModule &CGM) const override;
};
-void WindowsARMTargetCodeGenInfo::addStackProbeSizeTargetAttribute(
- const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
- if (!isa<FunctionDecl>(D))
- return;
- if (CGM.getCodeGenOpts().StackProbeSize == 4096)
- return;
-
- llvm::Function *F = cast<llvm::Function>(GV);
- F->addFnAttr("stack-probe-size",
- llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
-}
-
void WindowsARMTargetCodeGenInfo::setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index b669353..99c7b8e 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -3108,6 +3108,22 @@ void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
}
}
+void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ CXXStdlibType Type = GetCXXStdlibType(Args);
+ bool Profiling = Args.hasArg(options::OPT_pg);
+
+ switch (Type) {
+ case ToolChain::CST_Libcxx:
+ CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
+ break;
+
+ case ToolChain::CST_Libstdcxx:
+ CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
+ break;
+ }
+}
+
Tool *FreeBSD::buildAssembler() const {
return new tools::freebsd::Assembler(*this);
}
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index b6fd426..f940e58 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -722,6 +722,8 @@ public:
void AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
+ void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const override;
bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
bool isPIEDefault() const override;
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 1118335..b820f53 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -182,7 +182,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
return true;
unsigned NewLineColumn = getNewLineColumn(State);
- if (Current.isMemberAccess() &&
+ if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
State.Column + getLengthToNextOperator(Current) > Style.ColumnLimit &&
(State.Column > NewLineColumn ||
Current.NestingLevel < State.StartOfLineLevel))
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index f66e218..0d51ee1 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -634,7 +634,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
if (auto *CTD = CTSD->getSpecializedTemplate())
RD = CTD->getTemplatedDecl();
if (IsConstant &&
- !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
+ !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
+ RD->hasMutableFields())) {
// Variables with const-qualified type having no mutable member may be
// listed in a firstprivate clause, even if they are static data members.
DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
@@ -3204,7 +3205,7 @@ public:
NewVD->setInitStyle(VD->getInitStyle());
NewVD->setExceptionVariable(VD->isExceptionVariable());
NewVD->setNRVOVariable(VD->isNRVOVariable());
- NewVD->setCXXForRangeDecl(VD->isInExternCXXContext());
+ NewVD->setCXXForRangeDecl(VD->isCXXForRangeDecl());
NewVD->setConstexpr(VD->isConstexpr());
NewVD->setInitCapture(VD->isInitCapture());
NewVD->setPreviousDeclInSameBlockScope(
@@ -3249,14 +3250,20 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
Expr *Lower = Transform.TransformExpr(LBExpr).get();
if (!Upper || !Lower)
return nullptr;
- Upper = SemaRef.PerformImplicitConversion(Upper, UBExpr->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true)
- .get();
- Lower = SemaRef.PerformImplicitConversion(Lower, LBExpr->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true)
- .get();
+ if (!SemaRef.Context.hasSameType(Upper->getType(), UBExpr->getType())) {
+ Upper = SemaRef
+ .PerformImplicitConversion(Upper, UBExpr->getType(),
+ Sema::AA_Converting,
+ /*AllowExplicit=*/true)
+ .get();
+ }
+ if (!SemaRef.Context.hasSameType(Lower->getType(), LBExpr->getType())) {
+ Lower = SemaRef
+ .PerformImplicitConversion(Lower, LBExpr->getType(),
+ Sema::AA_Converting,
+ /*AllowExplicit=*/true)
+ .get();
+ }
if (!Upper || !Lower)
return nullptr;
@@ -3283,14 +3290,18 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
return nullptr;
// Upper - Lower [- 1] + Step
- auto NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
- if (NewStep.isInvalid())
- return nullptr;
- NewStep = SemaRef.PerformImplicitConversion(
- NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting,
- /*AllowExplicit=*/true);
+ auto *StepNoImp = Step->IgnoreImplicit();
+ auto NewStep = Transform.TransformExpr(StepNoImp);
if (NewStep.isInvalid())
return nullptr;
+ if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
+ StepNoImp->getType())) {
+ NewStep = SemaRef.PerformImplicitConversion(
+ NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ if (NewStep.isInvalid())
+ return nullptr;
+ }
Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
if (!Diff.isUsable())
return nullptr;
@@ -3301,14 +3312,17 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
return nullptr;
// (Upper - Lower [- 1] + Step) / Step
- NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
- if (NewStep.isInvalid())
- return nullptr;
- NewStep = SemaRef.PerformImplicitConversion(
- NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting,
- /*AllowExplicit=*/true);
+ NewStep = Transform.TransformExpr(StepNoImp);
if (NewStep.isInvalid())
return nullptr;
+ if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
+ StepNoImp->getType())) {
+ NewStep = SemaRef.PerformImplicitConversion(
+ NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ if (NewStep.isInvalid())
+ return nullptr;
+ }
Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
if (!Diff.isUsable())
return nullptr;
@@ -3324,10 +3338,12 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
: Type->hasSignedIntegerRepresentation();
Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
- Diff = SemaRef.PerformImplicitConversion(
- Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
- if (!Diff.isUsable())
- return nullptr;
+ if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
+ Diff = SemaRef.PerformImplicitConversion(
+ Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
+ if (!Diff.isUsable())
+ return nullptr;
+ }
}
if (LimitedType) {
unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
@@ -3340,10 +3356,12 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
QualType NewType = C.getIntTypeForBitwidth(
NewSize, Type->hasSignedIntegerRepresentation() ||
C.getTypeSize(Type) < NewSize);
- Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
- Sema::AA_Converting, true);
- if (!Diff.isUsable())
- return nullptr;
+ if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
+ Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
+ Sema::AA_Converting, true);
+ if (!Diff.isUsable())
+ return nullptr;
+ }
}
}
@@ -3360,12 +3378,16 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
auto NewUB = Transform.TransformExpr(UB);
if (NewLB.isInvalid() || NewUB.isInvalid())
return Cond;
- NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true);
- NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true);
+ if (!SemaRef.Context.hasSameType(NewLB.get()->getType(), LB->getType())) {
+ NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(),
+ Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ }
+ if (!SemaRef.Context.hasSameType(NewUB.get()->getType(), UB->getType())) {
+ NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(),
+ Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ }
if (NewLB.isInvalid() || NewUB.isInvalid())
return Cond;
auto CondExpr = SemaRef.BuildBinOp(
@@ -3373,9 +3395,11 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
: (TestIsStrictOp ? BO_GT : BO_GE),
NewLB.get(), NewUB.get());
if (CondExpr.isUsable()) {
- CondExpr = SemaRef.PerformImplicitConversion(
- CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
- /*AllowExplicit=*/true);
+ if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(),
+ SemaRef.Context.BoolTy))
+ CondExpr = SemaRef.PerformImplicitConversion(
+ CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
+ /*AllowExplicit=*/true);
}
SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
// Otherwise use original loop conditon and evaluate it in runtime.
@@ -3602,20 +3626,26 @@ static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc,
ExprResult VarRef, ExprResult Start) {
TransformToNewDefs Transform(SemaRef);
// Build 'VarRef = Start.
- auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit());
- if (NewStart.isInvalid())
- return ExprError();
- NewStart = SemaRef.PerformImplicitConversion(
- NewStart.get(), Start.get()->IgnoreImplicit()->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true);
+ auto *StartNoImp = Start.get()->IgnoreImplicit();
+ auto NewStart = Transform.TransformExpr(StartNoImp);
if (NewStart.isInvalid())
return ExprError();
- NewStart = SemaRef.PerformImplicitConversion(
- NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
- /*AllowExplicit=*/true);
- if (!NewStart.isUsable())
- return ExprError();
+ if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
+ StartNoImp->getType())) {
+ NewStart = SemaRef.PerformImplicitConversion(
+ NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ if (NewStart.isInvalid())
+ return ExprError();
+ }
+ if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
+ VarRef.get()->getType())) {
+ NewStart = SemaRef.PerformImplicitConversion(
+ NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ if (!NewStart.isUsable())
+ return ExprError();
+ }
auto Init =
SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
@@ -3633,31 +3663,37 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S,
!Step.isUsable())
return ExprError();
+ auto *StepNoImp = Step.get()->IgnoreImplicit();
TransformToNewDefs Transform(SemaRef);
- auto NewStep = Transform.TransformExpr(Step.get()->IgnoreImplicit());
- if (NewStep.isInvalid())
- return ExprError();
- NewStep = SemaRef.PerformImplicitConversion(
- NewStep.get(), Step.get()->IgnoreImplicit()->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true);
+ auto NewStep = Transform.TransformExpr(StepNoImp);
if (NewStep.isInvalid())
return ExprError();
+ if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
+ StepNoImp->getType())) {
+ NewStep = SemaRef.PerformImplicitConversion(
+ NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ if (NewStep.isInvalid())
+ return ExprError();
+ }
ExprResult Update =
SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
if (!Update.isUsable())
return ExprError();
// Build 'VarRef = Start + Iter * Step'.
- auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit());
- if (NewStart.isInvalid())
- return ExprError();
- NewStart = SemaRef.PerformImplicitConversion(
- NewStart.get(), Start.get()->IgnoreImplicit()->getType(),
- Sema::AA_Converting,
- /*AllowExplicit=*/true);
+ auto *StartNoImp = Start.get()->IgnoreImplicit();
+ auto NewStart = Transform.TransformExpr(StartNoImp);
if (NewStart.isInvalid())
return ExprError();
+ if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
+ StartNoImp->getType())) {
+ NewStart = SemaRef.PerformImplicitConversion(
+ NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
+ /*AllowExplicit=*/true);
+ if (NewStart.isInvalid())
+ return ExprError();
+ }
Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add),
NewStart.get(), Update.get());
if (!Update.isUsable())
diff --git a/test/CodeGen/arm-vfp-asm-constraint.c b/test/CodeGen/arm-vfp-asm-constraint.c
new file mode 100644
index 0000000..21f7362
--- /dev/null
+++ b/test/CodeGen/arm-vfp-asm-constraint.c
@@ -0,0 +1,36 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple armv7-unknown-unknown -mfpmath vfp -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-NOT: error:
+
+double fabs(double x) { // CHECK-LABEL: @fabs(
+ // CHECK: call double asm "vabs.f64 ${0:P}, ${1:P}", "=w,w"(double
+ __asm__("vabs.f64 %P0, %P1"
+ : "=w"(x)
+ : "w"(x));
+ return x;
+}
+
+float fabsf(float x) { // CHECK-LABEL: @fabsf(
+ // CHECK: call float asm "vabs.f32 $0, $1", "=t,t"(float
+ __asm__("vabs.f32 %0, %1"
+ : "=t"(x)
+ : "t"(x));
+ return x;
+}
+
+double sqrt(double x) { // CHECK-LABEL: @sqrt(
+ // CHECK: call double asm "vsqrt.f64 ${0:P}, ${1:P}", "=w,w"(double
+ __asm__("vsqrt.f64 %P0, %P1"
+ : "=w"(x)
+ : "w"(x));
+ return x;
+}
+
+float sqrtf(float x) { // CHECK-LABEL: @sqrtf(
+ // CHECK: call float asm "vsqrt.f32 $0, $1", "=t,t"(float
+ __asm__("vsqrt.f32 %0, %1"
+ : "=t"(x)
+ : "t"(x));
+ return x;
+}
diff --git a/test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp b/test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp
new file mode 100644
index 0000000..235d8a0
--- /dev/null
+++ b/test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple thumbv7--windows-msvc -S -emit-llvm -o - -x c++ %s | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7--windows-itanium -fno-use-cxa-atexit -S -emit-llvm -o - -x c++ %s | FileCheck %s
+
+class C {
+public:
+ ~C();
+};
+
+static C sc;
+void f(const C &ci) { sc = ci; }
+
+// CHECK: atexit
+
diff --git a/test/Driver/freebsd.cpp b/test/Driver/freebsd.cpp
index dea3267..175b873 100644
--- a/test/Driver/freebsd.cpp
+++ b/test/Driver/freebsd.cpp
@@ -2,5 +2,12 @@
// RUN: | FileCheck --check-prefix=CHECK-TEN %s
// RUN: %clangxx %s -### -o %t.o -target amd64-unknown-freebsd9.2 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NINE %s
-// CHECK-TEN: -lc++
-// CHECK-NINE: -lstdc++
+// CHECK-TEN: "-lc++" "-lm"
+// CHECK-NINE: "-lstdc++" "-lm"
+
+// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd10.0 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-PG-TEN %s
+// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd9.2 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-PG-NINE %s
+// CHECK-PG-TEN: "-lc++_p" "-lm_p"
+// CHECK-PG-NINE: "-lstdc++_p" "-lm_p"
diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp
index 8fd82e7..3510b90 100644
--- a/test/OpenMP/for_ast_print.cpp
+++ b/test/OpenMP/for_ast_print.cpp
@@ -68,6 +68,18 @@ int main(int argc, char **argv) {
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
// CHECK-NEXT: for (int j = 0; j < 10; ++j)
// CHECK-NEXT: foo();
+ char buf[9] = "01234567";
+ char *p, *q;
+#pragma omp parallel
+#pragma omp for
+ for (p = buf; p < &buf[8]; p++)
+ for (q = &buf[0]; q <= buf + 7; q++)
+ foo();
+ // CHECK: #pragma omp parallel
+ // CHECK-NEXT: #pragma omp for
+ // CHECK-NEXT: for (p = buf; p < &buf[8]; p++)
+ // CHECK-NEXT: for (q = &buf[0]; q <= buf + 7; q++)
+ // CHECK-NEXT: foo();
return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
}
diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp
index 36abd8d..ea559b0 100644
--- a/test/OpenMP/for_lastprivate_codegen.cpp
+++ b/test/OpenMP/for_lastprivate_codegen.cpp
@@ -396,20 +396,9 @@ int main() {
// CHECK: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]]
// CHECK: [[LAST_THEN]]
-// Calculate last iter count
-// CHECK: store i32 1, i32* [[OMP_IV]]
-// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 [[IV1_1]], 1
-// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[OMP_IV]]
-// Actual copying.
-
-// original cnt=private_cnt;
// Calculate private cnt value.
-// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]
-// CHECK: [[MUL:%.+]] = mul nsw i32 [[IV1_1]], 1
-// CHECK: [[ADD:%.+]] = add nsw i32 0, [[MUL]]
-// CHECK: [[CONV:%.+]] = trunc i32 [[ADD]] to i8
-// CHECK: store i8 [[CONV]], i8* [[CNT_PRIV]]
+// CHECK: store i8 2, i8* [[CNT_PRIV]]
+// original cnt=private_cnt;
// CHECK: [[CNT_VAL:%.+]] = load i8, i8* [[CNT_PRIV]],
// CHECK: store i8 [[CNT_VAL]], i8* [[CNT]],
diff --git a/test/OpenMP/parallel_messages.cpp b/test/OpenMP/parallel_messages.cpp
index 8aee841..4db55a0 100644
--- a/test/OpenMP/parallel_messages.cpp
+++ b/test/OpenMP/parallel_messages.cpp
@@ -5,7 +5,12 @@ void foo() {
#pragma omp parallel // expected-error {{unexpected OpenMP directive '#pragma omp parallel'}}
+struct S;
+S& bar();
int main(int argc, char **argv) {
+ S &s = bar();
+ #pragma omp parallel
+ (void)&s;
#pragma omp parallel { // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
foo();
#pragma omp parallel ( // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 30fd603..d9a16db 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -6135,6 +6135,9 @@ TEST_F(FormatTest, FormatsArrays) {
" .aaaaaaaaaaaaaaaaaaaaaa();");
verifyNoCrash("a[,Y?)]", getLLVMStyleWithColumns(10));
+
+ FormatStyle NoColumnLimit = getLLVMStyleWithColumns(0);
+ verifyFormat("aaaaa[bbbbbb].cccccc()", NoColumnLimit);
}
TEST_F(FormatTest, LineStartsWithSpecialCharacter) {
OpenPOWER on IntegriCloud