summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib')
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp93
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp15
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.h2
-rw-r--r--contrib/llvm/tools/clang/lib/Format/ContinuationIndenter.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp166
7 files changed, 155 insertions, 143 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 4f0b124..af8aea0 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 59821a8..d0ee891 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
index 4566fdb..cdb325f 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
+++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index b669353..99c7b8e 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
index b6fd426..f940e58 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h
+++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Format/ContinuationIndenter.cpp b/contrib/llvm/tools/clang/lib/Format/ContinuationIndenter.cpp
index 1118335..b820f53 100644
--- a/contrib/llvm/tools/clang/lib/Format/ContinuationIndenter.cpp
+++ b/contrib/llvm/tools/clang/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/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
index f66e218..0d51ee1 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
+++ b/contrib/llvm/tools/clang/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())
OpenPOWER on IntegriCloud