Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Aug 2015 14:41:35 +0000 (UTC)
From:      Brooks Davis <brooks@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r394411 - in head/devel/llvm37: . files
Message-ID:  <201508161441.t7GEfZkx006594@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: brooks
Date: Sun Aug 16 14:41:34 2015
New Revision: 394411
URL: https://svnweb.freebsd.org/changeset/ports/394411

Log:
  Apply a couple upstream clang patches to hopefully fix a crash building
  blender with clang and openmp.
  
  Reported by:	Shane Ambler <FreeBSD@ShaneWare.Biz>

Added:
  head/devel/llvm37/files/clang-patch-svn-244209   (contents, props changed)
  head/devel/llvm37/files/clang-patch-svn-245041   (contents, props changed)
Modified:
  head/devel/llvm37/Makefile

Modified: head/devel/llvm37/Makefile
==============================================================================
--- head/devel/llvm37/Makefile	Sun Aug 16 14:18:07 2015	(r394410)
+++ head/devel/llvm37/Makefile	Sun Aug 16 14:41:34 2015	(r394411)
@@ -2,6 +2,7 @@
 
 PORTNAME=	llvm
 DISTVERSION=	3.7.0rc2
+PORTREVISION=	1
 CATEGORIES=	devel lang
 MASTER_SITES=	http://llvm.org/${PRE_}releases/${LLVM_RELEASE}/${RCDIR}
 DISTNAME=	${PORTNAME}-${DISTVERSION}.src
@@ -37,7 +38,10 @@ OPTIONS_DEFAULT_amd64=	OPENMP
 OPTIONS_SUB=	yes
 
 CLANG_DESC=	Build clang
-CLANG_EXTRA_PATCHES= ${PATCHDIR}/clang-patch-tools_clang_lib_Headers_CMakeLists.txt
+CLANG_EXTRA_PATCHES= \
+		${PATCHDIR}/clang-patch-tools_clang_lib_Headers_CMakeLists.txt \
+		${PATCHDIR}/clang-patch-svn-244209 \
+		${PATCHDIR}/clang-patch-svn-245041
 CLANG_CONFLICTS_INSTALL=	clang-devel-3.[1234567]*
 CLANG_DISTFILES=	cfe-${DISTVERSION}.src${EXTRACT_SUFX}
 CLANG_CMAKE_ON=		-DCLANG_DEFAULT_OPENMP_RUNTIME=libomp
@@ -266,4 +270,16 @@ check-commands:
 	test -e ${STAGEDIR}${LLVM_PREFIX}/bin/${command}
 .endfor
 
+.if make(svn-patch-clang)
+.if !defined(PATCH_REV)
+.error svn-patch-clang requires that PATCH_REV be set
+.endif
+_PATCH_FILE=${FILESDIR}/clang-patch-svn-${PATCH_REV}
+_LLVM_BASE=http://llvm.org/svn/llvm-project/cfe/trunk
+svn-patch-clang:
+	svn log -c ${PATCH_REV} ${_LLVM_BASE} >> ${_PATCH_FILE}
+	svn diff -c ${PATCH_REV} ${_LLVM_BASE} | \
+	    sed -E -e 's;^(---|\+\+\+) ;\1 tools/clang/;' >> ${_PATCH_FILE}
+.endif
+
 .include <bsd.port.post.mk>

Added: head/devel/llvm37/files/clang-patch-svn-244209
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/llvm37/files/clang-patch-svn-244209	Sun Aug 16 14:41:34 2015	(r394411)
@@ -0,0 +1,688 @@
+------------------------------------------------------------------------
+r244209 | abataev | 2015-08-06 12:30:57 +0000 (Thu, 06 Aug 2015) | 4 lines
+
+[OPENMP 4.1] Allow references in init expression for loop-based constructs.
+
+OpenMP 4.1 allows to use variables with reference types in private clauses and, therefore, in init expressions of the cannonical loop forms.
+
+------------------------------------------------------------------------
+Index: lib/CodeGen/CGStmtOpenMP.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CGStmtOpenMP.cpp	(revision 244208)
++++ tools/clang/lib/CodeGen/CGStmtOpenMP.cpp	(revision 244209)
+@@ -680,15 +680,22 @@
+ 
+ static void emitPrivateLoopCounters(CodeGenFunction &CGF,
+                                     CodeGenFunction::OMPPrivateScope &LoopScope,
+-                                    ArrayRef<Expr *> Counters) {
++                                    ArrayRef<Expr *> Counters,
++                                    ArrayRef<Expr *> PrivateCounters) {
++  auto I = PrivateCounters.begin();
+   for (auto *E : Counters) {
+-    auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
+-    (void)LoopScope.addPrivate(VD, [&]() -> llvm::Value *{
++    auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
++    auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
++    llvm::Value *Addr;
++    (void)LoopScope.addPrivate(PrivateVD, [&]() -> llvm::Value * {
+       // Emit var without initialization.
+-      auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
++      auto VarEmission = CGF.EmitAutoVarAlloca(*PrivateVD);
+       CGF.EmitAutoVarCleanups(VarEmission);
+-      return VarEmission.getAllocatedAddress();
++      Addr = VarEmission.getAllocatedAddress();
++      return Addr;
+     });
++    (void)LoopScope.addPrivate(VD, [&]() -> llvm::Value * { return Addr; });
++    ++I;
+   }
+ }
+ 
+@@ -697,7 +704,8 @@
+                         llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
+   {
+     CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
+-    emitPrivateLoopCounters(CGF, PreCondScope, S.counters());
++    emitPrivateLoopCounters(CGF, PreCondScope, S.counters(),
++                            S.private_counters());
+     const VarDecl *IVDecl =
+         cast<VarDecl>(cast<DeclRefExpr>(S.getIterationVariable())->getDecl());
+     bool IsRegistered = PreCondScope.addPrivate(IVDecl, [&]() -> llvm::Value *{
+@@ -835,7 +843,8 @@
+     bool HasLastprivateClause;
+     {
+       OMPPrivateScope LoopScope(CGF);
+-      emitPrivateLoopCounters(CGF, LoopScope, S.counters());
++      emitPrivateLoopCounters(CGF, LoopScope, S.counters(),
++                              S.private_counters());
+       emitPrivateLinearVars(CGF, S, LoopScope);
+       CGF.EmitOMPPrivateClause(S, LoopScope);
+       CGF.EmitOMPReductionClauseInit(S, LoopScope);
+@@ -1124,7 +1133,8 @@
+       EmitOMPPrivateClause(S, LoopScope);
+       HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
+       EmitOMPReductionClauseInit(S, LoopScope);
+-      emitPrivateLoopCounters(*this, LoopScope, S.counters());
++      emitPrivateLoopCounters(*this, LoopScope, S.counters(),
++                              S.private_counters());
+       emitPrivateLinearVars(*this, S, LoopScope);
+       (void)LoopScope.Privatize();
+ 
+Index: lib/Serialization/ASTWriterStmt.cpp
+===================================================================
+--- tools/clang/lib/Serialization/ASTWriterStmt.cpp	(revision 244208)
++++ tools/clang/lib/Serialization/ASTWriterStmt.cpp	(revision 244209)
+@@ -1957,6 +1957,9 @@
+   for (auto I : D->counters()) {
+     Writer.AddStmt(I);
+   }
++  for (auto I : D->private_counters()) {
++    Writer.AddStmt(I);
++  }
+   for (auto I : D->updates()) {
+     Writer.AddStmt(I);
+   }
+Index: lib/Serialization/ASTReaderStmt.cpp
+===================================================================
+--- tools/clang/lib/Serialization/ASTReaderStmt.cpp	(revision 244208)
++++ tools/clang/lib/Serialization/ASTReaderStmt.cpp	(revision 244209)
+@@ -2113,6 +2113,10 @@
+   Sub.clear();
+   for (unsigned i = 0; i < CollapsedNum; ++i)
+     Sub.push_back(Reader.ReadSubExpr());
++  D->setPrivateCounters(Sub);
++  Sub.clear();
++  for (unsigned i = 0; i < CollapsedNum; ++i)
++    Sub.push_back(Reader.ReadSubExpr());
+   D->setUpdates(Sub);
+   Sub.clear();
+   for (unsigned i = 0; i < CollapsedNum; ++i)
+Index: lib/Sema/SemaOpenMP.cpp
+===================================================================
+--- tools/clang/lib/Sema/SemaOpenMP.cpp	(revision 244208)
++++ tools/clang/lib/Sema/SemaOpenMP.cpp	(revision 244209)
+@@ -2251,6 +2251,9 @@
+   Expr *BuildPreCond(Scope *S, Expr *Cond) const;
+   /// \brief Build reference expression to the counter be used for codegen.
+   Expr *BuildCounterVar() const;
++  /// \brief Build reference expression to the private counter be used for
++  /// codegen.
++  Expr *BuildPrivateCounterVar() const;
+   /// \brief Build initization of the counter be used for codegen.
+   Expr *BuildCounterInit() const;
+   /// \brief Build step of the counter be used for codegen.
+@@ -2414,7 +2417,7 @@
+   } else if (auto DS = dyn_cast<DeclStmt>(S)) {
+     if (DS->isSingleDecl()) {
+       if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
+-        if (Var->hasInit()) {
++        if (Var->hasInit() && !Var->getType()->isReferenceType()) {
+           // Accept non-canonical init form here but emit ext. warning.
+           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
+             SemaRef.Diag(S->getLocStart(),
+@@ -2699,9 +2702,21 @@
+ 
+ /// \brief Build reference expression to the counter be used for codegen.
+ Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const {
+-  return buildDeclRefExpr(SemaRef, Var, Var->getType(), DefaultLoc);
++  return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(),
++                          DefaultLoc);
+ }
+ 
++Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
++  if (Var && !Var->isInvalidDecl()) {
++    auto Type = Var->getType().getNonReferenceType();
++    auto *PrivateVar = buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName());
++    if (PrivateVar->isInvalidDecl())
++      return nullptr;
++    return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
++  }
++  return nullptr;
++}
++
+ /// \brief Build initization of the counter be used for codegen.
+ Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
+ 
+@@ -2717,6 +2732,8 @@
+   Expr *NumIterations;
+   /// \brief The loop counter variable.
+   Expr *CounterVar;
++  /// \brief Private loop counter variable.
++  Expr *PrivateCounterVar;
+   /// \brief This is initializer for the initial value of #CounterVar.
+   Expr *CounterInit;
+   /// \brief This is step for the #CounterVar used to generate its update:
+@@ -2801,7 +2818,7 @@
+   //   A variable of signed or unsigned integer type.
+   //   For C++, a variable of a random access iterator type.
+   //   For C, a variable of a pointer type.
+-  auto VarType = Var->getType();
++  auto VarType = Var->getType().getNonReferenceType();
+   if (!VarType->isDependentType() && !VarType->isIntegerType() &&
+       !VarType->isPointerType() &&
+       !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
+@@ -2877,6 +2894,7 @@
+   ResultIterSpace.NumIterations = ISC.BuildNumIterations(
+       DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind));
+   ResultIterSpace.CounterVar = ISC.BuildCounterVar();
++  ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
+   ResultIterSpace.CounterInit = ISC.BuildCounterInit();
+   ResultIterSpace.CounterStep = ISC.BuildCounterStep();
+   ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
+@@ -2887,6 +2905,7 @@
+   HasErrors |= (ResultIterSpace.PreCond == nullptr ||
+                 ResultIterSpace.NumIterations == nullptr ||
+                 ResultIterSpace.CounterVar == nullptr ||
++                ResultIterSpace.PrivateCounterVar == nullptr ||
+                 ResultIterSpace.CounterInit == nullptr ||
+                 ResultIterSpace.CounterStep == nullptr);
+ 
+@@ -3286,6 +3305,7 @@
+       }
+       // Save results
+       Built.Counters[Cnt] = IS.CounterVar;
++      Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
+       Built.Updates[Cnt] = Update.get();
+       Built.Finals[Cnt] = Final.get();
+     }
+Index: lib/AST/Stmt.cpp
+===================================================================
+--- tools/clang/lib/AST/Stmt.cpp	(revision 244208)
++++ tools/clang/lib/AST/Stmt.cpp	(revision 244209)
+@@ -1496,6 +1496,13 @@
+   std::copy(A.begin(), A.end(), getCounters().begin());
+ }
+ 
++void OMPLoopDirective::setPrivateCounters(ArrayRef<Expr *> A) {
++  assert(A.size() == getCollapsedNumber() && "Number of loop private counters "
++                                             "is not the same as the collapsed "
++                                             "number");
++  std::copy(A.begin(), A.end(), getPrivateCounters().begin());
++}
++
+ void OMPLoopDirective::setUpdates(ArrayRef<Expr *> A) {
+   assert(A.size() == getCollapsedNumber() &&
+          "Number of counter updates is not the same as the collapsed number");
+@@ -1661,6 +1668,7 @@
+   Dir->setInit(Exprs.Init);
+   Dir->setInc(Exprs.Inc);
+   Dir->setCounters(Exprs.Counters);
++  Dir->setPrivateCounters(Exprs.PrivateCounters);
+   Dir->setUpdates(Exprs.Updates);
+   Dir->setFinals(Exprs.Finals);
+   return Dir;
+@@ -1707,6 +1715,7 @@
+   Dir->setNextLowerBound(Exprs.NLB);
+   Dir->setNextUpperBound(Exprs.NUB);
+   Dir->setCounters(Exprs.Counters);
++  Dir->setPrivateCounters(Exprs.PrivateCounters);
+   Dir->setUpdates(Exprs.Updates);
+   Dir->setFinals(Exprs.Finals);
+   return Dir;
+@@ -1753,6 +1762,7 @@
+   Dir->setNextLowerBound(Exprs.NLB);
+   Dir->setNextUpperBound(Exprs.NUB);
+   Dir->setCounters(Exprs.Counters);
++  Dir->setPrivateCounters(Exprs.PrivateCounters);
+   Dir->setUpdates(Exprs.Updates);
+   Dir->setFinals(Exprs.Finals);
+   return Dir;
+@@ -1908,6 +1918,7 @@
+   Dir->setNextLowerBound(Exprs.NLB);
+   Dir->setNextUpperBound(Exprs.NUB);
+   Dir->setCounters(Exprs.Counters);
++  Dir->setPrivateCounters(Exprs.PrivateCounters);
+   Dir->setUpdates(Exprs.Updates);
+   Dir->setFinals(Exprs.Finals);
+   return Dir;
+@@ -1952,6 +1963,7 @@
+   Dir->setNextLowerBound(Exprs.NLB);
+   Dir->setNextUpperBound(Exprs.NUB);
+   Dir->setCounters(Exprs.Counters);
++  Dir->setPrivateCounters(Exprs.PrivateCounters);
+   Dir->setUpdates(Exprs.Updates);
+   Dir->setFinals(Exprs.Finals);
+   return Dir;
+Index: test/OpenMP/for_loop_messages.cpp
+===================================================================
+--- tools/clang/test/OpenMP/for_loop_messages.cpp	(revision 244208)
++++ tools/clang/test/OpenMP/for_loop_messages.cpp	(revision 244209)
+@@ -66,24 +66,24 @@
+     c[(int)fi] = a[(int)fi] + b[(int)fi];
+   }
+ #pragma omp parallel
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (int &ref = ii; ref < 10; ref++) {
+   }
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (int i; i < 10; i++)
+     c[i] = a[i];
+ 
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (int i = 0, j = 0; i < 10; ++i)
+     c[i] = a[i];
+ 
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (; ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -90,13 +90,13 @@
+ 
+ #pragma omp parallel
+ // expected-warning@+3 {{expression result unused}}
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (ii + 1; ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (c[ii] = 0; ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -446,7 +446,7 @@
+   for (GoodIter I = begin; I < end; ++I)
+     ++I;
+ #pragma omp parallel
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (GoodIter &I = begin; I < end; ++I)
+     ++I;
+@@ -485,7 +485,7 @@
+   for (begin = begin0; begin < end; ++begin)
+     ++begin;
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for
+   for (++begin; begin < end; ++begin)
+     ++begin;
+Index: test/OpenMP/parallel_for_loop_messages.cpp
+===================================================================
+--- tools/clang/test/OpenMP/parallel_for_loop_messages.cpp	(revision 244208)
++++ tools/clang/test/OpenMP/parallel_for_loop_messages.cpp	(revision 244209)
+@@ -54,32 +54,32 @@
+   for (double fi = 0; fi < 10.0; fi++) {
+     c[(int)fi] = a[(int)fi] + b[(int)fi];
+   }
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (int &ref = ii; ref < 10; ref++) {
+   }
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (int i; i < 10; i++)
+     c[i] = a[i];
+ 
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (int i = 0, j = 0; i < 10; ++i)
+     c[i] = a[i];
+ 
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (; ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+ // expected-warning@+3 {{expression result unused}}
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (ii + 1; ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (c[ii] = 0; ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -374,7 +374,7 @@
+ #pragma omp parallel for
+   for (GoodIter I = begin; I < end; ++I)
+     ++I;
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (GoodIter &I = begin; I < end; ++I)
+     ++I;
+@@ -405,7 +405,7 @@
+ #pragma omp parallel for
+   for (begin = begin0; begin < end; ++begin)
+     ++begin;
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for
+   for (++begin; begin < end; ++begin)
+     ++begin;
+Index: test/OpenMP/simd_loop_messages.cpp
+===================================================================
+--- tools/clang/test/OpenMP/simd_loop_messages.cpp	(revision 244208)
++++ tools/clang/test/OpenMP/simd_loop_messages.cpp	(revision 244209)
+@@ -45,32 +45,32 @@
+   for (double fi = 0; fi < 10.0; fi++) {
+     c[(int)fi] = a[(int)fi] + b[(int)fi];
+   }
+-  // expected-error@+2 {{variable must be of integer or random access iterator type}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (int &ref = ii; ref < 10; ref++) {
+   }
+-  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (int i; i < 10; i++)
+     c[i] = a[i];
+ 
+-  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (int i = 0, j = 0; i < 10; ++i)
+     c[i] = a[i];
+ 
+-  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (;ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+   // expected-warning@+3 {{expression result unused}}
+-  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (ii + 1;ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+-  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (c[ii] = 0;ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -364,7 +364,7 @@
+   #pragma omp simd
+   for (GoodIter I = begin; I < end; ++I)
+     ++I;
+-  // expected-error@+2 {{variable must be of integer or random access iterator type}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (GoodIter &I = begin; I < end; ++I)
+     ++I;
+@@ -393,7 +393,7 @@
+   #pragma omp simd
+   for (begin = GoodIter(1,2); begin < end; ++begin)
+     ++begin;
+-  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++  // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+   #pragma omp simd
+   for (++begin; begin < end; ++begin)
+     ++begin;
+Index: test/OpenMP/parallel_for_simd_loop_messages.cpp
+===================================================================
+--- tools/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp	(revision 244208)
++++ tools/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp	(revision 244209)
+@@ -54,32 +54,32 @@
+   for (double fi = 0; fi < 10.0; fi++) {
+     c[(int)fi] = a[(int)fi] + b[(int)fi];
+   }
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (int &ref = ii; ref < 10; ref++) {
+   }
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (int i; i < 10; i++)
+     c[i] = a[i];
+ 
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (int i = 0, j = 0; i < 10; ++i)
+     c[i] = a[i];
+ 
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (; ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+ // expected-warning@+3 {{expression result unused}}
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (ii + 1; ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (c[ii] = 0; ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -375,7 +375,7 @@
+ #pragma omp parallel for simd
+   for (GoodIter I = begin; I < end; ++I)
+     ++I;
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (GoodIter &I = begin; I < end; ++I)
+     ++I;
+@@ -406,7 +406,7 @@
+ #pragma omp parallel for simd
+   for (begin = begin0; begin < end; ++begin)
+     ++begin;
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp parallel for simd
+   for (++begin; begin < end; ++begin)
+     ++begin;
+Index: test/OpenMP/for_codegen.cpp
+===================================================================
+--- tools/clang/test/OpenMP/for_codegen.cpp	(revision 244208)
++++ tools/clang/test/OpenMP/for_codegen.cpp	(revision 244209)
+@@ -411,6 +411,21 @@
+   }
+ }
+ 
++// CHECK-LABEL: for_with_references
++void for_with_references() {
++// CHECK: [[I:%.+]] = alloca i8,
++// CHECK: [[CNT:%.+]] = alloca i8*,
++// CHECK: [[CNT_PRIV:%.+]] = alloca i8,
++// CHECK: call void @__kmpc_for_static_init_4(
++// CHECK-NOT: load i8, i8* [[CNT]],
++// CHECK: call void @__kmpc_for_static_fini(
++  char i = 0;
++  char &cnt = i;
++#pragma omp for
++  for (cnt = 0; cnt < 2; ++cnt)
++    k = cnt;
++}
++
+ struct Bool {
+   Bool(bool b) : b(b) {}
+   operator bool() const { return b; }
+Index: test/OpenMP/for_simd_loop_messages.cpp
+===================================================================
+--- tools/clang/test/OpenMP/for_simd_loop_messages.cpp	(revision 244208)
++++ tools/clang/test/OpenMP/for_simd_loop_messages.cpp	(revision 244209)
+@@ -63,24 +63,24 @@
+     c[(int)fi] = a[(int)fi] + b[(int)fi];
+   }
+ #pragma omp parallel
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (int &ref = ii; ref < 10; ref++) {
+   }
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (int i; i < 10; i++)
+     c[i] = a[i];
+ 
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (int i = 0, j = 0; i < 10; ++i)
+     c[i] = a[i];
+ 
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (; ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -87,13 +87,13 @@
+ 
+ #pragma omp parallel
+ // expected-warning@+3 {{expression result unused}}
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (ii + 1; ii < 10; ++ii)
+     c[ii] = a[ii];
+ 
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (c[ii] = 0; ii < 10; ++ii)
+     c[ii] = a[ii];
+@@ -430,7 +430,7 @@
+   for (GoodIter I = begin; I < end; ++I)
+     ++I;
+ #pragma omp parallel
+-// expected-error@+2 {{variable must be of integer or random access iterator type}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (GoodIter &I = begin; I < end; ++I)
+     ++I;
+@@ -469,7 +469,7 @@
+   for (begin = begin0; begin < end; ++begin)
+     ++begin;
+ #pragma omp parallel
+-// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
++// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp for simd
+   for (++begin; begin < end; ++begin)
+     ++begin;
+Index: include/clang/Basic/DiagnosticSemaKinds.td
+===================================================================
+--- tools/clang/include/clang/Basic/DiagnosticSemaKinds.td	(revision 244208)
++++ tools/clang/include/clang/Basic/DiagnosticSemaKinds.td	(revision 244209)
+@@ -7545,8 +7545,8 @@
+ def err_omp_local_var_in_threadprivate_init : Error<
+   "variable with local storage in initial value of threadprivate variable">;
+ def err_omp_loop_not_canonical_init : Error<
+-  "initialization clause of OpenMP for loop must be of the form "
+-  "'var = init' or 'T var = init'">;
++  "initialization clause of OpenMP for loop is not in canonical form "
++  "('var = init' or 'T var = init')">;
+ def ext_omp_loop_not_canonical_init : ExtWarn<
+   "initialization clause of OpenMP for loop is not in canonical form "
+   "('var = init' or 'T var = init')">, InGroup<OpenMPLoopForm>;
+Index: include/clang/AST/StmtOpenMP.h
+===================================================================
+--- tools/clang/include/clang/AST/StmtOpenMP.h	(revision 244208)
++++ tools/clang/include/clang/AST/StmtOpenMP.h	(revision 244209)
+@@ -311,11 +311,18 @@
+     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+   }
+ 
++  /// \brief Get the private counters storage.
++  MutableArrayRef<Expr *> getPrivateCounters() {
++    Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
++        child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
++    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
++  }
++
+   /// \brief Get the updates storage.
+   MutableArrayRef<Expr *> getUpdates() {
+     Expr **Storage = reinterpret_cast<Expr **>(
+         &*std::next(child_begin(),
+-                    getArraysOffset(getDirectiveKind()) + CollapsedNum));
++                    getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
+     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+   }
+ 
+@@ -323,7 +330,7 @@
+   MutableArrayRef<Expr *> getFinals() {
+     Expr **Storage = reinterpret_cast<Expr **>(
+         &*std::next(child_begin(),
+-                    getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
++                    getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
+     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+   }
+ 
+@@ -358,7 +365,7 @@
+   static unsigned numLoopChildren(unsigned CollapsedNum,
+                                   OpenMPDirectiveKind Kind) {
+     return getArraysOffset(Kind) +
+-           3 * CollapsedNum; // Counters, Updates and Finals
++           4 * CollapsedNum; // Counters, PrivateCounters, Updates and Finals
+   }
+ 
+   void setIterationVariable(Expr *IV) {
+@@ -414,6 +421,7 @@
+     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
+   }
+   void setCounters(ArrayRef<Expr *> A);
++  void setPrivateCounters(ArrayRef<Expr *> A);
+   void setUpdates(ArrayRef<Expr *> A);
+   void setFinals(ArrayRef<Expr *> A);
+ 
+@@ -453,6 +461,8 @@
+     Expr *NUB;
+     /// \brief Counters Loop counters.
+     SmallVector<Expr *, 4> Counters;
++    /// \brief PrivateCounters Loop counters.
++    SmallVector<Expr *, 4> PrivateCounters;
+     /// \brief Expressions for loop counters update for CodeGen.
+     SmallVector<Expr *, 4> Updates;
+     /// \brief Final loop counter values for GodeGen.
+@@ -484,10 +494,12 @@
+       NLB = nullptr;
+       NUB = nullptr;
+       Counters.resize(Size);
++      PrivateCounters.resize(Size);
+       Updates.resize(Size);
+       Finals.resize(Size);
+       for (unsigned i = 0; i < Size; ++i) {
+         Counters[i] = nullptr;
++        PrivateCounters[i] = nullptr;
+         Updates[i] = nullptr;
+         Finals[i] = nullptr;
+       }
+@@ -584,6 +596,12 @@
+     return const_cast<OMPLoopDirective *>(this)->getCounters();
+   }
+ 
++  ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
++
++  ArrayRef<Expr *> private_counters() const {
++    return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
++  }
++
+   ArrayRef<Expr *> updates() { return getUpdates(); }
+ 
+   ArrayRef<Expr *> updates() const {

Added: head/devel/llvm37/files/clang-patch-svn-245041
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/llvm37/files/clang-patch-svn-245041	Sun Aug 16 14:41:34 2015	(r394411)
@@ -0,0 +1,707 @@
+------------------------------------------------------------------------
+r245041 | abataev | 2015-08-14 12:25:37 +0000 (Fri, 14 Aug 2015) | 4 lines
+
+[OPENMP] Fix for http://llvm.org/PR24371: Assert failure compiling blender 2.75.
+blender uses statements expression in condition of the loop under control of the '#pragma omp parallel for'. This condition is used several times in different expressions required for codegen of the loop directive. If there are some variables defined in statement expression, it fires an assert during codegen because of redefinition of the same variables.
+We have to rebuild several expression to be sure that all variables are unique.
+
+------------------------------------------------------------------------
+Index: lib/Sema/SemaOpenMP.cpp
+===================================================================
+--- tools/clang/lib/Sema/SemaOpenMP.cpp	(revision 245040)
++++ tools/clang/lib/Sema/SemaOpenMP.cpp	(revision 245041)
+@@ -12,6 +12,7 @@
+ ///
+ //===----------------------------------------------------------------------===//
+ 
++#include "TreeTransform.h"
+ #include "clang/AST/ASTContext.h"
+ #include "clang/AST/ASTMutationListener.h"
+ #include "clang/AST/Decl.h"
+@@ -2609,20 +2610,85 @@
+   return true;
+ }
+ 
++namespace {
++// Transform variables declared in GNU statement expressions to new ones to
++// avoid crash on codegen.
++class TransformToNewDefs : public TreeTransform<TransformToNewDefs> {
++  typedef TreeTransform<TransformToNewDefs> BaseTransform;
++
++public:
++  TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {}
++
++  Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
++    if (auto *VD = cast<VarDecl>(D))
++      if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) &&
++          !isa<ImplicitParamDecl>(D)) {
++        auto *NewVD = VarDecl::Create(
++            SemaRef.Context, VD->getDeclContext(), VD->getLocStart(),
++            VD->getLocation(), VD->getIdentifier(), VD->getType(),
++            VD->getTypeSourceInfo(), VD->getStorageClass());
++        NewVD->setTSCSpec(VD->getTSCSpec());
++        NewVD->setInit(VD->getInit());
++        NewVD->setInitStyle(VD->getInitStyle());
++        NewVD->setExceptionVariable(VD->isExceptionVariable());
++        NewVD->setNRVOVariable(VD->isNRVOVariable());
++        NewVD->setCXXForRangeDecl(VD->isInExternCXXContext());
++        NewVD->setConstexpr(VD->isConstexpr());
++        NewVD->setInitCapture(VD->isInitCapture());
++        NewVD->setPreviousDeclInSameBlockScope(
++            VD->isPreviousDeclInSameBlockScope());
++        VD->getDeclContext()->addHiddenDecl(NewVD);
++        transformedLocalDecl(VD, NewVD);
++        return NewVD;
++      }
++    return BaseTransform::TransformDefinition(Loc, D);
++  }
++
++  ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
++    if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl()))
++      if (E->getDecl() != NewD) {
++        NewD->setReferenced();
++        NewD->markUsed(SemaRef.Context);
++        return DeclRefExpr::Create(
++            SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(),
++            cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(),
++            E->getNameInfo(), E->getType(), E->getValueKind());
++      }
++    return BaseTransform::TransformDeclRefExpr(E);
++  }
++};
++}
++
+ /// \brief Build the expression to calculate the number of iterations.
+ Expr *
+ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
+                                                 const bool LimitedType) const {
++  TransformToNewDefs Transform(SemaRef);
+   ExprResult Diff;
+-  if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() ||
++  auto VarType = Var->getType().getNonReferenceType();
++  if (VarType->isIntegerType() || VarType->isPointerType() ||
+       SemaRef.getLangOpts().CPlusPlus) {
+     // Upper - Lower
+-    Expr *Upper = TestIsLessOp ? UB : LB;
+-    Expr *Lower = TestIsLessOp ? LB : UB;
++    auto *UBExpr = TestIsLessOp ? UB : LB;
++    auto *LBExpr = TestIsLessOp ? LB : UB;
++    Expr *Upper = Transform.TransformExpr(UBExpr).get();
++    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 (!Upper || !Lower)
++      return nullptr;
+ 
+     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
+ 
+-    if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) {
++    if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
+       // BuildBinOp already emitted error, this one is to point user to upper
+       // and lower bound, and to tell what is passed to 'operator-'.
+       SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
+@@ -2643,8 +2709,15 @@
+     return nullptr;
+ 
+   // Upper - Lower [- 1] + Step
+-  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(),
+-                            Step->IgnoreImplicit());
++  auto NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
++  if (NewStep.isInvalid())
++    return nullptr;
++  NewStep = SemaRef.PerformImplicitConversion(
++      NewStep.get(), Step->IgnoreImplicit()->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;
+ 
+@@ -2654,15 +2727,35 @@
+     return nullptr;
+ 
+   // (Upper - Lower [- 1] + Step) / Step
+-  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(),
+-                            Step->IgnoreImplicit());
++  NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
++  if (NewStep.isInvalid())
++    return nullptr;
++  NewStep = SemaRef.PerformImplicitConversion(
++      NewStep.get(), Step->IgnoreImplicit()->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;
+ 
+   // OpenMP runtime requires 32-bit or 64-bit loop variables.
++  QualType Type = Diff.get()->getType();
++  auto &C = SemaRef.Context;
++  bool UseVarType = VarType->hasIntegerRepresentation() &&
++                    C.getTypeSize(Type) > C.getTypeSize(VarType);
++  if (!Type->isIntegerType() || UseVarType) {
++    unsigned NewSize =
++        UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
++    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 (LimitedType) {
+-    auto &C = SemaRef.Context;
+-    QualType Type = Diff.get()->getType();
+     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
+     if (NewSize != C.getTypeSize(Type)) {
+       if (NewSize < C.getTypeSize(Type)) {
+@@ -2671,7 +2764,8 @@
+             << InitSrcRange << ConditionSrcRange;
+       }
+       QualType NewType = C.getIntTypeForBitwidth(
+-          NewSize, Type->hasSignedIntegerRepresentation());
++          NewSize, Type->hasSignedIntegerRepresentation() ||
++                       C.getTypeSize(Type) < NewSize);
+       Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
+                                                Sema::AA_Converting, true);
+       if (!Diff.isUsable())
+@@ -2686,10 +2780,24 @@
+   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
+   bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
+   SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
++  TransformToNewDefs Transform(SemaRef);
++
++  auto NewLB = Transform.TransformExpr(LB);
++  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 (NewLB.isInvalid() || NewUB.isInvalid())
++    return Cond;
+   auto CondExpr = SemaRef.BuildBinOp(
+       S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
+                                   : (TestIsStrictOp ? BO_GT : BO_GE),
+-      LB, UB);
++      NewLB.get(), NewUB.get());
+   if (CondExpr.isUsable()) {
+     CondExpr = SemaRef.PerformImplicitConversion(
+         CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
+@@ -2912,6 +3020,31 @@
+   return HasErrors;
+ }
+ 
++/// \brief Build 'VarRef = Start.
++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);
++  if (NewStart.isInvalid())
++    return ExprError();
++  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());
++  return Init;
++}
++
+ /// \brief Build 'VarRef = Start + Iter * Step'.
+ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S,
+                                      SourceLocation Loc, ExprResult VarRef,
+@@ -2923,14 +3056,33 @@
+       !Step.isUsable())
+     return ExprError();
+ 
+-  ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(),
+-                                         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);
++  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);
++  if (NewStart.isInvalid())
++    return ExprError();

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508161441.t7GEfZkx006594>