Index: head/devel/llvm60/Makefile =================================================================== --- head/devel/llvm60/Makefile (revision 489224) +++ head/devel/llvm60/Makefile (revision 489225) @@ -1,569 +1,569 @@ # $FreeBSD$ PORTNAME= llvm DISTVERSION= 6.0.1 -PORTREVISION= 4 +PORTREVISION= 5 CATEGORIES= devel lang MASTER_SITES= http://${PRE_}releases.llvm.org/${LLVM_RELEASE}/${RCDIR} PKGNAMESUFFIX= ${LLVM_SUFFIX} DISTNAME= ${PORTNAME}-${DISTVERSION}.src DISTFILES= ${PORTNAME}-${DISTVERSION}.src${EXTRACT_SUFX} MAINTAINER= brooks@FreeBSD.org COMMENT= LLVM and Clang .include "${.CURDIR}/../llvm-devel/Makefile.LICENSE" LLVM_RELEASE= ${DISTVERSION:C/rc.*//} LLVM_MAJOR= ${LLVM_RELEASE:C/\.[0-9]$//} LLVM_LIB_VER= ${LLVM_MAJOR:C/\.//} RCDIR= ${DISTVERSION:S/${LLVM_RELEASE}//:C|(rc.*)|\1/|} PRE_= ${DISTVERSION:C/.*rc.*/pre/:N*[0-9]*} LLVM_SUFFIX= ${LLVM_LIB_VER} LLVM_PREFIX= ${PREFIX}/llvm${LLVM_SUFFIX} DOCSDIR= ${PREFIX}/share/doc/${PORTNAME}${LLVM_SUFFIX} DATADIR= ${PREFIX}/share/${PORTNAME}${LLVM_SUFFIX} USES= cmake compiler:c++11-lib libedit perl5 tar:xz \ shebangfix _USES_PYTHON?= python:2.7,build USES+= ${_USES_PYTHON} USE_LDCONFIG= ${LLVM_PREFIX}/lib SHEBANG_FILES= utils/lit/lit.py utils/llvm-lit/llvm-lit.in SUB_FILES= llvm-wrapper.sh SUB_LIST= LLVM_PREFIX="${LLVM_PREFIX}" LLVM_SUFFIX="${LLVM_SUFFIX}" CMAKE_INSTALL_PREFIX= ${LLVM_PREFIX} CMAKE_ARGS= -DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON CMAKE_ARGS+= -DLLVM_ENABLE_RTTI=ON CMAKE_ARGS+= -DLLVM_DEFAULT_TARGET_TRIPLE=${CONFIGURE_TARGET} CMAKE_ARGS+= -DLLVM_HOST_TRIPLE=${CONFIGURE_TARGET} # Following commit https://github.com/kitware/cmake/commit/956054 # we need to either change the whole man-shuffle below, or simply # redefine CMAKE_INSTALL_MANDIR CMAKE_ARGS+= -DCMAKE_INSTALL_MANDIR:PATH="share/man" CMAKE_ARGS+= -DLLVM_PARALLEL_LINK_JOBS=1 OPTIONS_DEFINE= CLANG DOCS EXTRAS LIT LLD LLDB OPTIONS_DEFINE_amd64= COMPILER_RT GOLD OPENMP OPTIONS_DEFINE_i386= COMPILER_RT OPENMP OPTIONS_DEFAULT= CLANG EXTRAS LIT LLD LLDB OPTIONS_DEFAULT_amd64= COMPILER_RT GOLD OPENMP OPTIONS_DEFAULT_i386= COMPILER_RT OPENMP OPTIONS_SUB= yes CLANG_DESC= Build clang CLANG_EXTRA_PATCHES= ${PATCHDIR}/clang CLANG_CONFLICTS_INSTALL= clang-devel-3.[1234567]* CLANG_DISTFILES= cfe-${DISTVERSION}.src${EXTRACT_SUFX} CLANG_CMAKE_ON= -DCLANG_DEFAULT_OPENMP_RUNTIME=libomp CLANG_PORTDOCS= clang CLANG_USE= GNOME=libxml2 COMPILER_RT_DESC= Sanitizer libraries COMPILER_RT_DISTFILES= compiler-rt-${DISTVERSION}.src${EXTRACT_SUFX} COMPILER_RT_PLIST_FILES=${_COMPILER_RT_LIBS:S|^|${_CRTLIBDIR}/|} DOCS_BUILD_DEPENDS= sphinx-build:textproc/py-sphinx DOCS_PORTDOCS= llvm DOCS_CMAKE_ON= -DLLVM_ENABLE_SPHINX=ON \ -DSPHINX_WARNINGS_AS_ERRORS=OFF \ -DLLVM_BUILD_DOCS=ON DOCS_PLIST_FILES= ${MAN1SRCS:S|^|man/man1/|:S|.1$|${LLVM_SUFFIX}.1.gz|} EXTRAS_DESC= Extra clang tools EXTRAS_IMPLIES= CLANG EXTRAS_DISTFILES= clang-tools-extra-${DISTVERSION}.src${EXTRACT_SUFX} GOLD_DESC= Build the LLVM Gold plugin for LTO GOLD_CMAKE_ON= -DLLVM_BINUTILS_INCDIR=${LOCALBASE}/include GOLD_BUILD_DEPENDS= ${LOCALBASE}/bin/ld.gold:devel/binutils LIT_DESC= Install lit and FileCheck test tools LIT_VARS= _USES_PYTHON=python:2.7 LLD_DESC= Install lld, the LLVM linker LLD_DISTFILES= lld-${DISTVERSION}.src${EXTRACT_SUFX} LLD_EXTRA_PATCHES= ${PATCHDIR}/lld LLDB_BUILD_DEPENDS= swig3.0:devel/swig30 \ ${PY_ENUM34} LLDB_DESC= Install lldb, the LLVM debugger LLDB_DISTFILES= lldb-${DISTVERSION}.src${EXTRACT_SUFX} LLDB_EXTRA_PATCHES= ${PATCHDIR}/lldb LLDB_IMPLIES= CLANG LLDB_VARS= _USES_PYTHON=python:2.7 OPENMP_DESC= Install libomp, the LLVM OpenMP runtime library OPENMP_DISTFILES= openmp-${DISTVERSION}.src${EXTRACT_SUFX} OPENMP_EXTRA_PATCHES= ${PATCHDIR}/openmp .if defined(WITH_DEBUG) CMAKE_BUILD_TYPE= RelWithDebInfo STRIP= .endif _CRTLIBDIR= ${LLVM_PREFIX:S|${PREFIX}/||}/lib/clang/${LLVM_RELEASE}/lib/freebsd # Emulate USE_GITHUB's ${WRKSRC_tag} to reduce diffs to ../llvm-devel .for option in CLANG COMPILER_RT EXTRAS LLD LLDB OPENMP WRKSRC_${option:tl}= ${WRKDIR}/${${option}_DISTFILES:S/${EXTRACT_SUFX}//} .endfor OPTIONS_SUB= yes PLIST_SUB+= LLVM_LIB_VER=${LLVM_LIB_VER} \ LLVM_MAJOR=${LLVM_MAJOR} \ LLVM_RELEASE=${LLVM_RELEASE} \ LLVM_SUFFIX=${LLVM_SUFFIX} COMMANDS= bugpoint \ llc \ lli \ llvm-ar \ llvm-as \ llvm-bcanalyzer \ llvm-cat \ llvm-cfi-verify \ llvm-config \ llvm-cov \ llvm-cvtres \ llvm-diff \ llvm-dis \ llvm-dlltool \ llvm-dwarfdump \ llvm-dwp \ llvm-extract \ llvm-link \ llvm-mc \ llvm-mcmarkup \ llvm-modextract \ llvm-mt \ llvm-nm \ llvm-objcopy \ llvm-objdump \ llvm-opt-report \ llvm-pdbutil \ llvm-profdata \ llvm-ranlib \ llvm-rc \ llvm-readelf \ llvm-readobj \ llvm-rtdyld \ llvm-size \ llvm-split \ llvm-stress \ llvm-strings \ llvm-symbolizer \ llvm-tblgen \ macho-dump \ opt \ sancov FIRST_COMMAND= ${COMMANDS:C/^/XXXX/1:MXXXX*:C/^XXXX//} STRIP_LIBS= BugpointPasses.so \ LLVMHello.so \ ${LIBNAME}.0 \ libLTO.so EXTRAS_COMMANDS+= \ clang-apply-replacements \ clang-change-namespace \ clang-include-fixer \ clang-modernize \ clang-query \ clang-rename \ clang-reorder-fields \ clang-tidy \ clangd \ find-all-symbols \ modularize EXTRAS_LIBS= libclangApplyReplacements \ libclangChangeNamespace \ libclangDaemon \ libclangIncludeFixer \ libclangMove \ libclangQuery \ libclangRename \ libclangReorderFields \ libclangTidy \ libclangTidyGoogleModule \ libclangTidyLLVMModule \ libclangTidyMiscModule \ libclangTidyReadabilityModule \ libclangTidyUtils \ libfindAllSymbols \ libmodernizeCore EXTRAS_PATTERN= ${EXTRAS_COMMANDS:tW:C/ */|/g}|${EXTRAS_LIBS:tW:C/ */|/g} .include # keep in sync with /usr/src/lib/clang/clang.build.mk # ----------- start of sync block ------------------ # Armv6 and armv7 uses hard float abi, unless the CPUTYPE has soft in it. # arm (for armv4 and armv5 CPUs) always uses the soft float ABI. # For all other targets, we stick with 'unknown'. .if ${ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") TARGET_ABI= -gnueabihf .elif ${ARCH:Marm*} TARGET_ABI= -gnueabi .else TARGET_ABI= .endif CONFIGURE_TARGET:=${ARCH:C/amd64/x86_64/:C/arm64/aarch64/}-portbld-${OPSYS:tl}${OSREL}${TARGET_ABI} # ----------- end of sync block -------------------- .if ${PORT_OPTIONS:MCLANG} COMMANDS+= c-index-test \ clang \ clang++ \ clang-check \ clang-cpp \ clang-format \ clang-func-mapping \ clang-import-test \ clang-offload-bundler \ scan-build \ scan-view MAN1SRCS+= clang.1 \ scan-build.1 CLANG_PATTERN= (c-index-test|clang|scan-|Reporter.py|ScanView.py|scanview.css|sorttable.js|startfile.py|-analyzer) SHEBANG_FILES+= tools/clang/tools/scan-view/bin/scan-view \ tools/clang/tools/clang-format/git-clang-format \ tools/clang/tools/clang-format/clang-format-diff.py USES+= gnome .endif .if ${PORT_OPTIONS:MCOMPILER_RT} COMPILER_RT_PATTERN= (_blacklist.txt|sanitizer|include.xray) .endif .if ${PORT_OPTIONS:MLIT} MAN1SRCS+= lit.1 FileCheck.1 LIT_COMMANDS= lit llvm-lit FileCheck .endif .if ${PORT_OPTIONS:MLLDB} COMMANDS+= lldb \ lldb-argdumper \ lldb-mi \ lldb-server \ lldb-test .endif .if ! ${OPTIONS_DEFINE:MCOMPILER_RT} # Hack to disable COMPILER_RT in plist of unsupported architectures PLIST_SUB+= COMPILER_RT="@comment " .else .endif .if ! ${OPTIONS_DEFINE:MGOLD} # Hack to disable GOLD in plist of unsupported architectures PLIST_SUB+= GOLD="@comment " .else .endif .if ! ${OPTIONS_DEFINE:MOPENMP} # Hack to disable OPENMP in plist of unsupported architectures PLIST_SUB+= OPENMP="@comment " .else .endif MAN1SRCS+= bugpoint.1 dsymutil.1 llc.1 lli.1 llvm-ar.1 llvm-as.1 \ llvm-bcanalyzer.1 llvm-build.1 llvm-config.1 llvm-cov.1 \ llvm-diff.1 llvm-dis.1 llvm-dwarfdump.1 \ llvm-extract.1 llvm-lib.1 llvm-link.1 llvm-nm.1 \ llvm-pdbutil.1 \ llvm-profdata.1 llvm-readobj.1 llvm-stress.1 llvm-symbolizer.1 \ opt.1 tblgen.1 .include .if ${ARCH} == "amd64" _COMPILER_RT_LIBS= \ libclang_rt.asan-preinit-x86_64.a \ libclang_rt.asan-x86_64.a \ libclang_rt.asan-x86_64.a.syms \ libclang_rt.asan-x86_64.so \ libclang_rt.asan_cxx-x86_64.a \ libclang_rt.asan_cxx-x86_64.a.syms \ libclang_rt.builtins-x86_64.a \ libclang_rt.dd-x86_64.a \ libclang_rt.dyndd-x86_64.so \ libclang_rt.lsan-x86_64.a \ libclang_rt.profile-x86_64.a \ libclang_rt.safestack-x86_64.a \ libclang_rt.stats-x86_64.a \ libclang_rt.stats_client-x86_64.a \ libclang_rt.tsan-x86_64.a \ libclang_rt.tsan-x86_64.a.syms \ libclang_rt.tsan_cxx-x86_64.a \ libclang_rt.tsan_cxx-x86_64.a.syms \ libclang_rt.ubsan_minimal-x86_64.a \ libclang_rt.ubsan_minimal-x86_64.a.syms \ libclang_rt.ubsan_minimal-x86_64.so \ libclang_rt.ubsan_standalone-x86_64.a \ libclang_rt.ubsan_standalone-x86_64.a.syms \ libclang_rt.ubsan_standalone-x86_64.so \ libclang_rt.ubsan_standalone_cxx-x86_64.a \ libclang_rt.ubsan_standalone_cxx-x86_64.a.syms .endif .if ${ARCH} == "i386" _COMPILER_RT_LIBS+= \ libclang_rt.asan-i386.a \ libclang_rt.asan-i386.so \ libclang_rt.asan-preinit-i386.a \ libclang_rt.asan_cxx-i386.a \ libclang_rt.builtins-i386.a \ libclang_rt.lsan-i386.a \ libclang_rt.profile-i386.a \ libclang_rt.safestack-i386.a \ libclang_rt.stats-i386.a \ libclang_rt.stats_client-i386.a \ libclang_rt.ubsan_minimal-i386.a \ libclang_rt.ubsan_minimal-i386.so \ libclang_rt.ubsan_standalone-i386.a \ libclang_rt.ubsan_standalone-i386.so \ libclang_rt.ubsan_standalone_cxx-i386.a .endif .if ${PORT_OPTIONS:MEXTRAS} COMMANDS+= ${EXTRAS_COMMANDS} MAN1SRCS+= extraclangtools.1 PORTDOCS+= clang-tools SHEBANG_FILES+= tools/clang/tools/extra/clang-tidy/tool/clang-tidy-diff.py \ tools/clang/tools/extra/clang-tidy/tool/run-clang-tidy.py \ tools/clang/tools/extra/include-fixer/find-all-symbols/tool/run-find-all-symbols.py .endif .if ${PORT_OPTIONS:MLLD} COMMANDS+= ld.lld \ ld64.lld \ lld \ lld-link \ wasm-ld PORTDOCS+= lld .endif .if ${OPSYS} == "FreeBSD" && ${COMPILER_TYPE} != clang CXXFLAGS+= -D_GLIBCXX_USE_C99 .endif .if ${ARCH} == "armv6" || ${ARCH} == "armv7" BUILD_DEPENDS+= ${LOCALBASE}/bin/ld:devel/binutils CONFIGURE_ENV+= COMPILER_PATH=${LOCALBASE}/bin MAKE_ENV+= COMPILER_PATH=${LOCALBASE}/bin .endif post-extract-CLANG-on: ${MV} ${WRKSRC_clang} ${PATCH_WRKSRC}/tools/clang post-extract-EXTRAS-on: ${MV} ${WRKSRC_extras} ${PATCH_WRKSRC}/tools/clang/tools/extra post-extract-LLD-on: ${MV} ${WRKSRC_lld} ${PATCH_WRKSRC}/tools/lld post-extract-LLDB-on: ${MV} ${WRKSRC_lldb} ${PATCH_WRKSRC}/tools/lldb post-extract-OPENMP-on: ${MV} ${WRKSRC_openmp} ${PATCH_WRKSRC}/projects/openmp post-patch: ${REINPLACE_CMD} -e 's|import lit|import lit${LLVM_SUFFIX}|' \ -e 's|from lit|from lit${LLVM_SUFFIX}|' \ -e 's|lit\.|lit${LLVM_SUFFIX}.|' \ ${WRKSRC}/utils/lit/lit.py ${WRKSRC}/utils/lit/lit/*.py \ ${WRKSRC}/utils/lit/lit/formats/*.py ${REINPLACE_CMD} -e 's,/usr/local/,${LOCALBASE}/,' \ ${WRKSRC}/CMakeLists.txt post-patch-CLANG-on: ${REINPLACE_CMD} -e 's|%%LLVM_PREFIX%%|${LLVM_PREFIX}|' \ ${PATCH_WRKSRC}/tools/clang/lib/Driver/ToolChains/CommonArgs.cpp ${REINPLACE_CMD} -e 's|%%LLVM_SUFFIX%%|${LLVM_SUFFIX}|' \ ${PATCH_WRKSRC}/tools/clang/tools/clang-format/clang-format.py \ ${PATCH_WRKSRC}/tools/clang/tools/clang-format/clang-format-sublime.py \ ${PATCH_WRKSRC}/tools/clang/tools/clang-format/git-clang-format post-build-COMPILER_RT-on: ${MKDIR} ${WRKDIR}/compiler-rt-build cd ${WRKDIR}/compiler-rt-build && \ ${SETENV} ${CONFIGURE_ENV} ${CMAKE_BIN} ${CMAKE_ARGS} \ -DLLVM_CONFIG_PATH=${CONFIGURE_WRKSRC}/bin/llvm-config \ ${WRKSRC_compiler_rt} && \ ${MAKE_ENV} ${MAKE_CMD} post-install: ${RM} -r ${STAGEDIR}${LLVM_PREFIX}/include/llvm/MC/MCAnalysis ${INSTALL_SCRIPT} ${WRKDIR}/llvm-wrapper.sh \ ${STAGEDIR}${PREFIX}/bin/${FIRST_COMMAND}${LLVM_SUFFIX} .for command in ${COMMANDS:C/^/XXXX/1:NXXXX*} ${LN} -f ${STAGEDIR}${PREFIX}/bin/${FIRST_COMMAND}${LLVM_SUFFIX} \ ${STAGEDIR}${PREFIX}/bin/${command}${LLVM_SUFFIX} .endfor post-install-DOCS-on: ${MV} ${STAGEDIR}${LLVM_PREFIX}/share/doc ${STAGEDIR}${DOCSDIR} .for _man in ${MAN1SRCS} ${MV} ${STAGEDIR}${LLVM_PREFIX}/share/man/man1/${_man} \ ${STAGEDIR}${MANPREFIX}/man/man1/${_man:R}${LLVM_SUFFIX}.1 .endfor .if ! ${PORT_OPTIONS:MLIT} ${RM} ${STAGEDIR}${LLVM_PREFIX}/share/man/man1/lit.1 ${RM} ${STAGEDIR}${LLVM_PREFIX}/share/man/man1/FileCheck.1 .endif ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/share/man/man1/ ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/share/man/ .if ${PORT_OPTIONS:MCLANG} post-install-DOCS-off: ${RM} ${STAGEDIR}${LLVM_PREFIX}/share/man/man1/scan-build.1 ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/share/man/man1/ ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/share/man/ .endif post-install-LLD-on: ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/include/llvm/BinaryFormat/WasmRelocs post-install-LLDB-on: ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/include/lldb/Host/windows/getopt ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/include/lldb/Host/mingw ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/include/lldb/Host/msvc post-install-CLANG-on: ${LN} -f ${STAGEDIR}${LLVM_PREFIX}/bin/clang \ ${STAGEDIR}${LLVM_PREFIX}/bin/clang-cpp ${INSTALL_PROGRAM} ${WRKDIR}/.build/bin/clang-tblgen \ ${STAGEDIR}${LLVM_PREFIX}/bin/ post-install-COMPILER_RT-on: cd ${WRKDIR}/compiler-rt-build && \ ${MAKE_ENV} ${MAKE_CMD} ${INSTALL_TARGET} .if ${ARCH} == "amd64" ${RM} ${STAGEDIR}${LLVM_PREFIX}/lib/freebsd/libclang_rt*i386* .endif ${MKDIR} ${STAGEDIR}${PREFIX}/${_CRTLIBDIR} ${MV} ${STAGEDIR}${LLVM_PREFIX}/lib/freebsd/* \ ${STAGEDIR}${PREFIX}/${_CRTLIBDIR} ${RMDIR} ${STAGEDIR}${LLVM_PREFIX}/lib/freebsd post-install-LIT-on: ${INSTALL_SCRIPT} ${PATCH_WRKSRC}/utils/lit/lit.py \ ${STAGEDIR}${LLVM_PREFIX}/bin/lit ${LN} -f ${STAGEDIR}${LLVM_PREFIX}/bin/lit \ ${STAGEDIR}${LLVM_PREFIX}/bin/llvm-lit ${LN} -f ${STAGEDIR}${LLVM_PREFIX}/bin/lit \ ${STAGEDIR}${PREFIX}/bin/lit${LLVM_SUFFIX} ${LN} -f ${STAGEDIR}${LLVM_PREFIX}/bin/lit \ ${STAGEDIR}${PREFIX}/bin/llvm-lit${LLVM_SUFFIX} ${MKDIR} ${STAGEDIR}${PYTHONPREFIX_SITELIBDIR}/lit${LLVM_SUFFIX} ${MKDIR} ${STAGEDIR}${PYTHONPREFIX_SITELIBDIR}/lit${LLVM_SUFFIX}/formats ${INSTALL_DATA} ${WRKSRC}/utils/lit/lit/*.py \ ${STAGEDIR}${PYTHONPREFIX_SITELIBDIR}/lit${LLVM_SUFFIX} ${INSTALL_DATA} ${WRKSRC}/utils/lit/lit/formats/*.py \ ${STAGEDIR}${PYTHONPREFIX_SITELIBDIR}/lit${LLVM_SUFFIX}/formats ${INSTALL_PROGRAM} ${WRKDIR}/.build/bin/FileCheck \ ${STAGEDIR}${LLVM_PREFIX}/bin/ ${LN} -f ${STAGEDIR}${LLVM_PREFIX}/bin/FileCheck \ ${STAGEDIR}${PREFIX}/bin/FileCheck${LLVM_SUFFIX} TEST_CMD= '(cd ${WRKSRC}/test; ${SETENV} ${MAKE_ENV} LD_LIBRARY_PATH=${WRKSRC}/Release/lib ${MAKE_CMD} check-local-lit)' do-test: if [ `${ID} -u` = 0 ]; then \ ${CHOWN} -R nobody ${WRKSRC}/test; \ su -m nobody -c ${TEST_CMD}; \ else \ ${SH} -c ${TEST_CMD}; \ fi build-plist: ${RM} ${PLIST} ${PLIST}.tmp ${ECHO_CMD} "@comment >>>>> GENERATED FILE, DO NOT EDIT <<<<<" >> ${PLIST}.tmp ${ECHO_CMD} "@comment Alter build-plist target and regenerate as required" >> ${PLIST}.tmp .for command in ${COMMANDS} ${ECHO_CMD} bin/${command}%%LLVM_SUFFIX%% >> ${PLIST}.tmp .endfor .for command in ${LIT_COMMANDS} ${ECHO_CMD} %%LIT%%bin/${command}%%LLVM_SUFFIX%% >> ${PLIST}.tmp ${ECHO_CMD} %%LIT%%${LLVM_PREFIX:S|${PREFIX}/||:C|${LLVM_SUFFIX}|%%LLVM_SUFFIX%%|}/bin/${command} >> ${PLIST}.tmp .endfor ${FIND} ${STAGEDIR}${LLVM_PREFIX} -type f -o -type l | \ ${GREP} -v '[/-]lit$$' | ${GREP} -v 'FileCheck$$' | \ ${GREP} -v man/man1 | ${SED} -e 's|${STAGEDIR}${PREFIX}/||' \ -e 's|${PYTHON_SITELIBDIR:C|${PREFIX}/||}|%%PYTHON_SITELIBDIR%%|' \ -e 's|${LLVM_RELEASE}|%%LLVM_RELEASE%%|' \ -e 's|release.cmake|%%CMAKE_BUILD_TYPE%%.cmake|' \ -e 's|${LLVM_RELEASE:C/\./\\./g}|%%LLVM_RELEASE%%|' \ -e 's|${LLVM_MAJOR:C/\./\\./}|%%LLVM_MAJOR%%|' \ -e 's|${LLVM_MAJOR:C/\.//}|%%LLVM_LIB_VER%%|' \ | ${SORT} >> ${PLIST}.tmp ${FIND} ${STAGEDIR}${PYTHON_SITELIBDIR}/lit${LLVM_SUFFIX} -type f | \ ${SED} -e 's|${STAGEDIR}${PYTHON_SITELIBDIR}|%%LIT%%%%PYTHON_SITELIBDIR%%|' \ -e 's|${LLVM_RELEASE:C/\./\\./g}|%%LLVM_RELEASE%%|' \ -e 's|${LLVM_MAJOR:C/\./\\./}|%%LLVM_MAJOR%%|' \ -e 's|lit${LLVM_SUFFIX}|lit%%LLVM_SUFFIX%%|' | \ ${SORT} >> ${PLIST}.tmp ${AWK} '{ \ if ($$0 ~ /${CLANG_PATTERN}/ && $$0 !~ /(omp.h|ompt.h|${EXTRAS_PATTERN}|libclang_rt)/) {printf "%%%%CLANG%%%%"} \ if ($$0 ~ /${COMPILER_RT_PATTERN}/) \ {printf "%%%%COMPILER_RT%%%%"} \ if ($$0 ~ /(${EXTRAS_PATTERN})/) {printf "%%%%EXTRAS%%%%"} \ if ($$0 ~ /lld|wasm-ld/ && $$0 !~ /lldb/) {printf "%%%%LLD%%%%"} \ if ($$0 ~ /(argdumper|lldb|six.py)/) {printf "%%%%LLDB%%%%"} \ if ($$0 ~ /lib.*omp|omp.h|ompt.h/) {printf "%%%%OPENMP%%%%"} \ if ($$0 ~ /LLVMgold/) {printf "%%%%GOLD%%%%"} \ if ($$0 !~ /libclang_rt/) {print}}' ${PLIST}.tmp >> ${PLIST} ${ECHO_CMD} '@postexec if type ccache-update-links >/dev/null 2>&1; then ccache-update-links -v; fi' >> ${PLIST} ${ECHO_CMD} '@postunexec if type ccache-update-links >/dev/null 2>&1; then ccache-update-links -v; fi' >> ${PLIST} ${RM} ${PLIST}.tmp check-commands: .for command in ${COMMANDS} test -e ${STAGEDIR}${LLVM_PREFIX}/bin/${command} .endfor .if make(svn-patch-llvm) .if !defined(PATCH_REV) .error svn-patch-llvm requires that PATCH_REV be set .endif _PATCH_FILE=${FILESDIR}/patch-svn-${PATCH_REV} _LLVM_BASE=http://llvm.org/svn/llvm-project/llvm/trunk svn-patch-llvm: svn log -c ${PATCH_REV} ${_LLVM_BASE} >> ${_PATCH_FILE} svn diff -c ${PATCH_REV} ${_LLVM_BASE} >> ${_PATCH_FILE} .endif .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 .if make(svn-patch-compiler-rt) .if !defined(PATCH_REV) .error svn-patch-compiler-rt requires that PATCH_REV be set .endif _PATCH_FILE=${FILESDIR}/compiler-rt/patch-svn-${PATCH_REV} _LLVM_BASE=http://llvm.org/svn/llvm-project/compiler-rt/trunk svn-patch-compiler-rt: svn log -c ${PATCH_REV} ${_LLVM_BASE} >> ${_PATCH_FILE} svn diff -c ${PATCH_REV} ${_LLVM_BASE} | \ ${SED} -E -e 's;^(---|\+\+\+) ;\1 tools/compiler-rt/;' >> ${_PATCH_FILE} .endif .if make(svn-patch-lldb) .if !defined(PATCH_REV) .error svn-patch-lldb requires that PATCH_REV be set .endif _PATCH_FILE=${FILESDIR}/lldb/patch-svn-${PATCH_REV} _LLVM_BASE=http://llvm.org/svn/llvm-project/lldb/trunk svn-patch-lldb: svn log -c ${PATCH_REV} ${_LLVM_BASE} >> ${_PATCH_FILE} svn diff -c ${PATCH_REV} ${_LLVM_BASE} | >> ${_PATCH_FILE} .endif .include Index: head/devel/llvm60/files/clang/patch-stable12-r342281.diff =================================================================== --- head/devel/llvm60/files/clang/patch-stable12-r342281.diff (nonexistent) +++ head/devel/llvm60/files/clang/patch-stable12-r342281.diff (revision 489225) @@ -0,0 +1,834 @@ +r342281 | dim | 2018-12-20 19:28:53 +0100 (Thu, 20 Dec 2018) | 24 lines + +Pull in r329671 from upstream clang trunk (by Akira Hatanaka): + + [ExprConstant] Use an AST node and a version number as a key to + create an APValue and retrieve it from map Temporaries. + + The version number is needed when a single AST node is visited + multiple times and is used to create APValues that are required to be + distinct from each other (for example, MaterializeTemporaryExprs in + default arguments and VarDecls in loops). + + rdar://problem/36505742 + + Differential Revision: https://reviews.llvm.org/D42776 + +This should fix 'Assertion failed: (Result.isUninit() && "temporary +created multiple times"), function createTemporary' errors (if +assertions are enabled, otherwise the compiler internal state might go +bad), when building the graphics/rawtherapee port. + +Direct commit to stable/11 and stable/12, since head already has clang +7.0.1, which includes this change. + +PR: 234144 + +Index: tools/clang/include/clang/AST/APValue.h +=================================================================== +--- tools/clang/include/clang/AST/APValue.h (revision 342280) ++++ tools/clang/include/clang/AST/APValue.h (revision 342281) +@@ -53,7 +53,58 @@ class APValue { + MemberPointer, + AddrLabelDiff + }; +- typedef llvm::PointerUnion LValueBase; ++ ++ class LValueBase { ++ public: ++ typedef llvm::PointerUnion PtrTy; ++ ++ LValueBase() : CallIndex(0), Version(0) {} ++ ++ template ++ LValueBase(T P, unsigned I = 0, unsigned V = 0) ++ : Ptr(P), CallIndex(I), Version(V) {} ++ ++ template ++ bool is() const { return Ptr.is(); } ++ ++ template ++ T get() const { return Ptr.get(); } ++ ++ template ++ T dyn_cast() const { return Ptr.dyn_cast(); } ++ ++ void *getOpaqueValue() const; ++ ++ bool isNull() const; ++ ++ explicit operator bool () const; ++ ++ PtrTy getPointer() const { ++ return Ptr; ++ } ++ ++ unsigned getCallIndex() const { ++ return CallIndex; ++ } ++ ++ void setCallIndex(unsigned Index) { ++ CallIndex = Index; ++ } ++ ++ unsigned getVersion() const { ++ return Version; ++ } ++ ++ bool operator==(const LValueBase &Other) const { ++ return Ptr == Other.Ptr && CallIndex == Other.CallIndex && ++ Version == Other.Version; ++ } ++ ++ private: ++ PtrTy Ptr; ++ unsigned CallIndex, Version; ++ }; ++ + typedef llvm::PointerIntPair BaseOrMemberType; + union LValuePathEntry { + /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item +@@ -135,15 +186,15 @@ class APValue { + } + APValue(const APValue &RHS); + APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); } +- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex, ++ APValue(LValueBase B, const CharUnits &O, NoLValuePath N, + bool IsNullPtr = false) + : Kind(Uninitialized) { +- MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr); ++ MakeLValue(); setLValue(B, O, N, IsNullPtr); + } + APValue(LValueBase B, const CharUnits &O, ArrayRef Path, +- bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false) ++ bool OnePastTheEnd, bool IsNullPtr = false) + : Kind(Uninitialized) { +- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr); ++ MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); + } + APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { + MakeArray(InitElts, Size); +@@ -255,6 +306,7 @@ class APValue { + bool hasLValuePath() const; + ArrayRef getLValuePath() const; + unsigned getLValueCallIndex() const; ++ unsigned getLValueVersion() const; + bool isNullPointer() const; + + APValue &getVectorElt(unsigned I) { +@@ -376,10 +428,10 @@ class APValue { + ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I); + } + void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, +- unsigned CallIndex, bool IsNullPtr); ++ bool IsNullPtr); + void setLValue(LValueBase B, const CharUnits &O, + ArrayRef Path, bool OnePastTheEnd, +- unsigned CallIndex, bool IsNullPtr); ++ bool IsNullPtr); + void setUnion(const FieldDecl *Field, const APValue &Value) { + assert(isUnion() && "Invalid accessor"); + ((UnionData*)(char*)Data.buffer)->Field = Field; +@@ -451,4 +503,14 @@ class APValue { + + } // end namespace clang. + ++namespace llvm { ++template<> struct DenseMapInfo { ++ static clang::APValue::LValueBase getEmptyKey(); ++ static clang::APValue::LValueBase getTombstoneKey(); ++ static unsigned getHashValue(const clang::APValue::LValueBase &Base); ++ static bool isEqual(const clang::APValue::LValueBase &LHS, ++ const clang::APValue::LValueBase &RHS); ++}; ++} ++ + #endif +Index: tools/clang/lib/AST/APValue.cpp +=================================================================== +--- tools/clang/lib/AST/APValue.cpp (revision 342280) ++++ tools/clang/lib/AST/APValue.cpp (revision 342281) +@@ -23,14 +23,57 @@ using namespace clang; + + namespace { + struct LVBase { +- llvm::PointerIntPair BaseAndIsOnePastTheEnd; ++ APValue::LValueBase Base; + CharUnits Offset; + unsigned PathLength; +- unsigned CallIndex; +- bool IsNullPtr; ++ bool IsNullPtr : 1; ++ bool IsOnePastTheEnd : 1; + }; + } + ++void *APValue::LValueBase::getOpaqueValue() const { ++ return Ptr.getOpaqueValue(); ++} ++ ++bool APValue::LValueBase::isNull() const { ++ return Ptr.isNull(); ++} ++ ++APValue::LValueBase::operator bool () const { ++ return static_cast(Ptr); ++} ++ ++clang::APValue::LValueBase ++llvm::DenseMapInfo::getEmptyKey() { ++ return clang::APValue::LValueBase( ++ DenseMapInfo::getEmptyKey(), ++ DenseMapInfo::getEmptyKey(), ++ DenseMapInfo::getEmptyKey()); ++} ++ ++clang::APValue::LValueBase ++llvm::DenseMapInfo::getTombstoneKey() { ++ return clang::APValue::LValueBase( ++ DenseMapInfo::getTombstoneKey(), ++ DenseMapInfo::getTombstoneKey(), ++ DenseMapInfo::getTombstoneKey()); ++} ++ ++unsigned llvm::DenseMapInfo::getHashValue( ++ const clang::APValue::LValueBase &Base) { ++ llvm::FoldingSetNodeID ID; ++ ID.AddPointer(Base.getOpaqueValue()); ++ ID.AddInteger(Base.getCallIndex()); ++ ID.AddInteger(Base.getVersion()); ++ return ID.ComputeHash(); ++} ++ ++bool llvm::DenseMapInfo::isEqual( ++ const clang::APValue::LValueBase &LHS, ++ const clang::APValue::LValueBase &RHS) { ++ return LHS == RHS; ++} ++ + struct APValue::LV : LVBase { + static const unsigned InlinePathSpace = + (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry); +@@ -150,11 +193,10 @@ APValue::APValue(const APValue &RHS) : Kind(Uninit + MakeLValue(); + if (RHS.hasLValuePath()) + setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(), +- RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex(), +- RHS.isNullPointer()); ++ RHS.isLValueOnePastTheEnd(), RHS.isNullPointer()); + else + setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(), +- RHS.getLValueCallIndex(), RHS.isNullPointer()); ++ RHS.isNullPointer()); + break; + case Array: + MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize()); +@@ -552,12 +594,12 @@ std::string APValue::getAsString(ASTContext &Ctx, + + const APValue::LValueBase APValue::getLValueBase() const { + assert(isLValue() && "Invalid accessor"); +- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer(); ++ return ((const LV*)(const void*)Data.buffer)->Base; + } + + bool APValue::isLValueOnePastTheEnd() const { + assert(isLValue() && "Invalid accessor"); +- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt(); ++ return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd; + } + + CharUnits &APValue::getLValueOffset() { +@@ -578,9 +620,14 @@ ArrayRef APValue::getLVa + + unsigned APValue::getLValueCallIndex() const { + assert(isLValue() && "Invalid accessor"); +- return ((const LV*)(const char*)Data.buffer)->CallIndex; ++ return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex(); + } + ++unsigned APValue::getLValueVersion() const { ++ assert(isLValue() && "Invalid accessor"); ++ return ((const LV*)(const char*)Data.buffer)->Base.getVersion(); ++} ++ + bool APValue::isNullPointer() const { + assert(isLValue() && "Invalid usage"); + return ((const LV*)(const char*)Data.buffer)->IsNullPtr; +@@ -587,13 +634,12 @@ bool APValue::isNullPointer() const { + } + + void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, +- unsigned CallIndex, bool IsNullPtr) { ++ bool IsNullPtr) { + assert(isLValue() && "Invalid accessor"); + LV &LVal = *((LV*)(char*)Data.buffer); +- LVal.BaseAndIsOnePastTheEnd.setPointer(B); +- LVal.BaseAndIsOnePastTheEnd.setInt(false); ++ LVal.Base = B; ++ LVal.IsOnePastTheEnd = false; + LVal.Offset = O; +- LVal.CallIndex = CallIndex; + LVal.resizePath((unsigned)-1); + LVal.IsNullPtr = IsNullPtr; + } +@@ -600,13 +646,12 @@ void APValue::setLValue(LValueBase B, const CharUn + + void APValue::setLValue(LValueBase B, const CharUnits &O, + ArrayRef Path, bool IsOnePastTheEnd, +- unsigned CallIndex, bool IsNullPtr) { ++ bool IsNullPtr) { + assert(isLValue() && "Invalid accessor"); + LV &LVal = *((LV*)(char*)Data.buffer); +- LVal.BaseAndIsOnePastTheEnd.setPointer(B); +- LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd); ++ LVal.Base = B; ++ LVal.IsOnePastTheEnd = IsOnePastTheEnd; + LVal.Offset = O; +- LVal.CallIndex = CallIndex; + LVal.resizePath(Path.size()); + memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry)); + LVal.IsNullPtr = IsNullPtr; +Index: tools/clang/lib/AST/ExprConstant.cpp +=================================================================== +--- tools/clang/lib/AST/ExprConstant.cpp (revision 342280) ++++ tools/clang/lib/AST/ExprConstant.cpp (revision 342281) +@@ -446,8 +446,8 @@ namespace { + + // Note that we intentionally use std::map here so that references to + // values are stable. +- typedef std::map MapTy; +- typedef MapTy::const_iterator temp_iterator; ++ typedef std::pair MapKeyTy; ++ typedef std::map MapTy; + /// Temporaries - Temporary lvalues materialized within this stack frame. + MapTy Temporaries; + +@@ -457,6 +457,20 @@ namespace { + /// Index - The call index of this call. + unsigned Index; + ++ /// The stack of integers for tracking version numbers for temporaries. ++ SmallVector TempVersionStack = {1}; ++ unsigned CurTempVersion = TempVersionStack.back(); ++ ++ unsigned getTempVersion() const { return TempVersionStack.back(); } ++ ++ void pushTempVersion() { ++ TempVersionStack.push_back(++CurTempVersion); ++ } ++ ++ void popTempVersion() { ++ TempVersionStack.pop_back(); ++ } ++ + // FIXME: Adding this to every 'CallStackFrame' may have a nontrivial impact + // on the overall stack usage of deeply-recursing constexpr evaluataions. + // (We should cache this map rather than recomputing it repeatedly.) +@@ -473,10 +487,36 @@ namespace { + APValue *Arguments); + ~CallStackFrame(); + +- APValue *getTemporary(const void *Key) { +- MapTy::iterator I = Temporaries.find(Key); +- return I == Temporaries.end() ? nullptr : &I->second; ++ // Return the temporary for Key whose version number is Version. ++ APValue *getTemporary(const void *Key, unsigned Version) { ++ MapKeyTy KV(Key, Version); ++ auto LB = Temporaries.lower_bound(KV); ++ if (LB != Temporaries.end() && LB->first == KV) ++ return &LB->second; ++ // Pair (Key,Version) wasn't found in the map. Check that no elements ++ // in the map have 'Key' as their key. ++ assert((LB == Temporaries.end() || LB->first.first != Key) && ++ (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) && ++ "Element with key 'Key' found in map"); ++ return nullptr; + } ++ ++ // Return the current temporary for Key in the map. ++ APValue *getCurrentTemporary(const void *Key) { ++ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX)); ++ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key) ++ return &std::prev(UB)->second; ++ return nullptr; ++ } ++ ++ // Return the version number of the current temporary for Key. ++ unsigned getCurrentTemporaryVersion(const void *Key) const { ++ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX)); ++ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key) ++ return std::prev(UB)->first.second; ++ return 0; ++ } ++ + APValue &createTemporary(const void *Key, bool IsLifetimeExtended); + }; + +@@ -606,7 +646,8 @@ namespace { + + /// EvaluatingObject - Pair of the AST node that an lvalue represents and + /// the call index that that lvalue was allocated in. +- typedef std::pair EvaluatingObject; ++ typedef std::pair> ++ EvaluatingObject; + + /// EvaluatingConstructors - Set of objects that are currently being + /// constructed. +@@ -625,8 +666,10 @@ namespace { + } + }; + +- bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex) { +- return EvaluatingConstructors.count(EvaluatingObject(Decl, CallIndex)); ++ bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex, ++ unsigned Version) { ++ return EvaluatingConstructors.count( ++ EvaluatingObject(Decl, {CallIndex, Version})); + } + + /// The current array initialization index, if we're performing array +@@ -722,7 +765,7 @@ namespace { + void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) { + EvaluatingDecl = Base; + EvaluatingDeclValue = &Value; +- EvaluatingConstructors.insert({Base, 0}); ++ EvaluatingConstructors.insert({Base, {0, 0}}); + } + + const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); } +@@ -1086,11 +1129,16 @@ namespace { + unsigned OldStackSize; + public: + ScopeRAII(EvalInfo &Info) +- : Info(Info), OldStackSize(Info.CleanupStack.size()) {} ++ : Info(Info), OldStackSize(Info.CleanupStack.size()) { ++ // Push a new temporary version. This is needed to distinguish between ++ // temporaries created in different iterations of a loop. ++ Info.CurrentCall->pushTempVersion(); ++ } + ~ScopeRAII() { + // Body moved to a static method to encourage the compiler to inline away + // instances of this class. + cleanup(Info, OldStackSize); ++ Info.CurrentCall->popTempVersion(); + } + private: + static void cleanup(EvalInfo &Info, unsigned OldStackSize) { +@@ -1170,7 +1218,8 @@ CallStackFrame::~CallStackFrame() { + + APValue &CallStackFrame::createTemporary(const void *Key, + bool IsLifetimeExtended) { +- APValue &Result = Temporaries[Key]; ++ unsigned Version = Info.CurrentCall->getTempVersion(); ++ APValue &Result = Temporaries[MapKeyTy(Key, Version)]; + assert(Result.isUninit() && "temporary created multiple times"); + Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended)); + return Result; +@@ -1262,27 +1311,27 @@ namespace { + struct LValue { + APValue::LValueBase Base; + CharUnits Offset; +- unsigned InvalidBase : 1; +- unsigned CallIndex : 31; + SubobjectDesignator Designator; +- bool IsNullPtr; ++ bool IsNullPtr : 1; ++ bool InvalidBase : 1; + + const APValue::LValueBase getLValueBase() const { return Base; } + CharUnits &getLValueOffset() { return Offset; } + const CharUnits &getLValueOffset() const { return Offset; } +- unsigned getLValueCallIndex() const { return CallIndex; } + SubobjectDesignator &getLValueDesignator() { return Designator; } + const SubobjectDesignator &getLValueDesignator() const { return Designator;} + bool isNullPointer() const { return IsNullPtr;} + ++ unsigned getLValueCallIndex() const { return Base.getCallIndex(); } ++ unsigned getLValueVersion() const { return Base.getVersion(); } ++ + void moveInto(APValue &V) const { + if (Designator.Invalid) +- V = APValue(Base, Offset, APValue::NoLValuePath(), CallIndex, +- IsNullPtr); ++ V = APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr); + else { + assert(!InvalidBase && "APValues can't handle invalid LValue bases"); + V = APValue(Base, Offset, Designator.Entries, +- Designator.IsOnePastTheEnd, CallIndex, IsNullPtr); ++ Designator.IsOnePastTheEnd, IsNullPtr); + } + } + void setFrom(ASTContext &Ctx, const APValue &V) { +@@ -1290,12 +1339,11 @@ namespace { + Base = V.getLValueBase(); + Offset = V.getLValueOffset(); + InvalidBase = false; +- CallIndex = V.getLValueCallIndex(); + Designator = SubobjectDesignator(Ctx, V); + IsNullPtr = V.isNullPointer(); + } + +- void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) { ++ void set(APValue::LValueBase B, bool BInvalid = false) { + #ifndef NDEBUG + // We only allow a few types of invalid bases. Enforce that here. + if (BInvalid) { +@@ -1308,7 +1356,6 @@ namespace { + Base = B; + Offset = CharUnits::fromQuantity(0); + InvalidBase = BInvalid; +- CallIndex = I; + Designator = SubobjectDesignator(getType(B)); + IsNullPtr = false; + } +@@ -1317,13 +1364,12 @@ namespace { + Base = (Expr *)nullptr; + Offset = CharUnits::fromQuantity(TargetVal); + InvalidBase = false; +- CallIndex = 0; + Designator = SubobjectDesignator(PointerTy->getPointeeType()); + IsNullPtr = true; + } + + void setInvalid(APValue::LValueBase B, unsigned I = 0) { +- set(B, I, true); ++ set(B, true); + } + + // Check that this LValue is not based on a null pointer. If it is, produce +@@ -1525,6 +1571,15 @@ static bool EvaluateAsRValue(EvalInfo &Info, const + // Misc utilities + //===----------------------------------------------------------------------===// + ++/// A helper function to create a temporary and set an LValue. ++template ++static APValue &createTemporary(const KeyTy *Key, bool IsLifetimeExtended, ++ LValue &LV, CallStackFrame &Frame) { ++ LV.set({Key, Frame.Info.CurrentCall->Index, ++ Frame.Info.CurrentCall->getTempVersion()}); ++ return Frame.createTemporary(Key, IsLifetimeExtended); ++} ++ + /// Negate an APSInt in place, converting it to a signed form if necessary, and + /// preserving its value (by extending by up to one bit as needed). + static void negateAsSigned(APSInt &Int) { +@@ -1854,7 +1909,7 @@ static const ValueDecl *GetLValueBaseDecl(const LV + } + + static bool IsLiteralLValue(const LValue &Value) { +- if (Value.CallIndex) ++ if (Value.getLValueCallIndex()) + return false; + const Expr *E = Value.Base.dyn_cast(); + return E && !isa(E); +@@ -2404,7 +2459,7 @@ static bool handleLValueToRValueConversion(EvalInf + /// \param Result Filled in with a pointer to the value of the variable. + static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, + const VarDecl *VD, CallStackFrame *Frame, +- APValue *&Result) { ++ APValue *&Result, const LValue *LVal) { + + // If this is a parameter to an active constexpr function call, perform + // argument substitution. +@@ -2423,7 +2478,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, co + + // If this is a local variable, dig out its value. + if (Frame) { +- Result = Frame->getTemporary(VD); ++ Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion()) ++ : Frame->getCurrentTemporary(VD); + if (!Result) { + // Assume variables referenced within a lambda's call operator that were + // not declared within the call operator are captures and during checking +@@ -3000,8 +3056,8 @@ static CompleteObject findCompleteObject(EvalInfo + } + + CallStackFrame *Frame = nullptr; +- if (LVal.CallIndex) { +- Frame = Info.getCallFrame(LVal.CallIndex); ++ if (LVal.getLValueCallIndex()) { ++ Frame = Info.getCallFrame(LVal.getLValueCallIndex()); + if (!Frame) { + Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1) + << AK << LVal.Base.is(); +@@ -3113,7 +3169,7 @@ static CompleteObject findCompleteObject(EvalInfo + } + } + +- if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal)) ++ if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal, &LVal)) + return CompleteObject(); + } else { + const Expr *Base = LVal.Base.dyn_cast(); +@@ -3155,7 +3211,7 @@ static CompleteObject findCompleteObject(EvalInfo + return CompleteObject(); + } + } else { +- BaseVal = Frame->getTemporary(Base); ++ BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion()); + assert(BaseVal && "missing value for temporary"); + } + +@@ -3175,7 +3231,9 @@ static CompleteObject findCompleteObject(EvalInfo + // During the construction of an object, it is not yet 'const'. + // FIXME: This doesn't do quite the right thing for const subobjects of the + // object under construction. +- if (Info.isEvaluatingConstructor(LVal.getLValueBase(), LVal.CallIndex)) { ++ if (Info.isEvaluatingConstructor(LVal.getLValueBase(), ++ LVal.getLValueCallIndex(), ++ LVal.getLValueVersion())) { + BaseType = Info.Ctx.getCanonicalType(BaseType); + BaseType.removeLocalConst(); + } +@@ -3212,7 +3270,7 @@ static bool handleLValueToRValueConversion(EvalInf + + // Check for special cases where there is no existing APValue to look at. + const Expr *Base = LVal.Base.dyn_cast(); +- if (Base && !LVal.CallIndex && !Type.isVolatileQualified()) { ++ if (Base && !LVal.getLValueCallIndex() && !Type.isVolatileQualified()) { + if (const CompoundLiteralExpr *CLE = dyn_cast(Base)) { + // In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the + // initializer until now for such expressions. Such an expression can't be +@@ -3715,8 +3773,7 @@ static bool EvaluateVarDecl(EvalInfo &Info, const + return true; + + LValue Result; +- Result.set(VD, Info.CurrentCall->Index); +- APValue &Val = Info.CurrentCall->createTemporary(VD, true); ++ APValue &Val = createTemporary(VD, true, Result, *Info.CurrentCall); + + const Expr *InitE = VD->getInit(); + if (!InitE) { +@@ -3772,6 +3829,19 @@ struct StmtResult { + /// The location containing the result, if any (used to support RVO). + const LValue *Slot; + }; ++ ++struct TempVersionRAII { ++ CallStackFrame &Frame; ++ ++ TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) { ++ Frame.pushTempVersion(); ++ } ++ ++ ~TempVersionRAII() { ++ Frame.popTempVersion(); ++ } ++}; ++ + } + + static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, +@@ -4329,7 +4399,8 @@ static bool HandleConstructorCall(const Expr *E, c + } + + EvalInfo::EvaluatingConstructorRAII EvalObj( +- Info, {This.getLValueBase(), This.CallIndex}); ++ Info, {This.getLValueBase(), ++ {This.getLValueCallIndex(), This.getLValueVersion()}}); + CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues); + + // FIXME: Creating an APValue just to hold a nonexistent return value is +@@ -4578,9 +4649,12 @@ class ExprEvaluatorBase + { return StmtVisitorTy::Visit(E->getResultExpr()); } + bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) + { return StmtVisitorTy::Visit(E->getReplacement()); } +- bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) +- { return StmtVisitorTy::Visit(E->getExpr()); } ++ bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { ++ TempVersionRAII RAII(*Info.CurrentCall); ++ return StmtVisitorTy::Visit(E->getExpr()); ++ } + bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) { ++ TempVersionRAII RAII(*Info.CurrentCall); + // The initializer may not have been parsed yet, or might be erroneous. + if (!E->getExpr()) + return Error(E); +@@ -4658,7 +4732,7 @@ class ExprEvaluatorBase + } + + bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) { +- if (APValue *Value = Info.CurrentCall->getTemporary(E)) ++ if (APValue *Value = Info.CurrentCall->getCurrentTemporary(E)) + return DerivedSuccess(*Value, E); + + const Expr *Source = E->getSourceExpr(); +@@ -5216,7 +5290,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr + + if (!VD->getType()->isReferenceType()) { + if (Frame) { +- Result.set(VD, Frame->Index); ++ Result.set({VD, Frame->Index, ++ Info.CurrentCall->getCurrentTemporaryVersion(VD)}); + return true; + } + return Success(VD); +@@ -5223,7 +5298,7 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr + } + + APValue *V; +- if (!evaluateVarDeclInit(Info, E, VD, Frame, V)) ++ if (!evaluateVarDeclInit(Info, E, VD, Frame, V, nullptr)) + return false; + if (V->isUninit()) { + if (!Info.checkingPotentialConstantExpression()) +@@ -5255,9 +5330,8 @@ bool LValueExprEvaluator::VisitMaterializeTemporar + *Value = APValue(); + Result.set(E); + } else { +- Value = &Info.CurrentCall-> +- createTemporary(E, E->getStorageDuration() == SD_Automatic); +- Result.set(E, Info.CurrentCall->Index); ++ Value = &createTemporary(E, E->getStorageDuration() == SD_Automatic, Result, ++ *Info.CurrentCall); + } + + QualType Type = Inner->getType(); +@@ -5736,7 +5810,6 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas + Result.Base = (Expr*)nullptr; + Result.InvalidBase = false; + Result.Offset = CharUnits::fromQuantity(N); +- Result.CallIndex = 0; + Result.Designator.setInvalid(); + Result.IsNullPtr = false; + return true; +@@ -5752,9 +5825,9 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas + if (!evaluateLValue(SubExpr, Result)) + return false; + } else { +- Result.set(SubExpr, Info.CurrentCall->Index); +- if (!EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr, false), +- Info, Result, SubExpr)) ++ APValue &Value = createTemporary(SubExpr, false, Result, ++ *Info.CurrentCall); ++ if (!EvaluateInPlace(Value, Info, Result, SubExpr)) + return false; + } + // The result is a pointer to the first element of the array. +@@ -6520,9 +6593,8 @@ class TemporaryExprEvaluator + + /// Visit an expression which constructs the value of this temporary. + bool VisitConstructExpr(const Expr *E) { +- Result.set(E, Info.CurrentCall->Index); +- return EvaluateInPlace(Info.CurrentCall->createTemporary(E, false), +- Info, Result, E); ++ APValue &Value = createTemporary(E, false, Result, *Info.CurrentCall); ++ return EvaluateInPlace(Value, Info, Result, E); + } + + bool VisitCastExpr(const CastExpr *E) { +@@ -8007,7 +8079,8 @@ static bool HasSameBase(const LValue &A, const LVa + } + + return IsGlobalLValue(A.getLValueBase()) || +- A.getLValueCallIndex() == B.getLValueCallIndex(); ++ (A.getLValueCallIndex() == B.getLValueCallIndex() && ++ A.getLValueVersion() == B.getLValueVersion()); + } + + /// \brief Determine whether this is a pointer past the end of the complete +@@ -9941,15 +10014,13 @@ static bool Evaluate(APValue &Result, EvalInfo &In + return true; + } else if (T->isArrayType()) { + LValue LV; +- LV.set(E, Info.CurrentCall->Index); +- APValue &Value = Info.CurrentCall->createTemporary(E, false); ++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall); + if (!EvaluateArray(E, LV, Value, Info)) + return false; + Result = Value; + } else if (T->isRecordType()) { + LValue LV; +- LV.set(E, Info.CurrentCall->Index); +- APValue &Value = Info.CurrentCall->createTemporary(E, false); ++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall); + if (!EvaluateRecord(E, LV, Value, Info)) + return false; + Result = Value; +@@ -9963,8 +10034,7 @@ static bool Evaluate(APValue &Result, EvalInfo &In + QualType Unqual = T.getAtomicUnqualifiedType(); + if (Unqual->isArrayType() || Unqual->isRecordType()) { + LValue LV; +- LV.set(E, Info.CurrentCall->Index); +- APValue &Value = Info.CurrentCall->createTemporary(E, false); ++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall); + if (!EvaluateAtomic(E, &LV, Value, Info)) + return false; + } else { +@@ -10786,7 +10856,7 @@ bool Expr::isPotentialConstantExpr(const FunctionD + // is a temporary being used as the 'this' pointer. + LValue This; + ImplicitValueInitExpr VIE(RD ? Info.Ctx.getRecordType(RD) : Info.Ctx.IntTy); +- This.set(&VIE, Info.CurrentCall->Index); ++ This.set({&VIE, Info.CurrentCall->Index}); + + ArrayRef Args; + +Index: tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp +=================================================================== +--- tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342280) ++++ tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342281) +@@ -852,7 +852,6 @@ namespace Lifetime { + static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} + static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} + +- // FIXME: This function should be treated as non-constant. + constexpr void lifetime_versus_loops() { + int *p = 0; + for (int i = 0; i != 2; ++i) { +@@ -862,10 +861,10 @@ namespace Lifetime { + if (i) + // This modifies the 'n' from the previous iteration of the loop outside + // its lifetime. +- ++*q; ++ ++*q; // expected-note {{increment of object outside its lifetime}} + } + } +- static_assert((lifetime_versus_loops(), true), ""); ++ static_assert((lifetime_versus_loops(), true), ""); // expected-error {{constant expression}} expected-note {{in call}} + } + + namespace Bitfields { +Index: tools/clang/test/SemaCXX/constexpr-default-arg.cpp +=================================================================== +--- tools/clang/test/SemaCXX/constexpr-default-arg.cpp (nonexistent) ++++ tools/clang/test/SemaCXX/constexpr-default-arg.cpp (revision 342281) +@@ -0,0 +1,38 @@ ++// RUN: %clang_cc1 -std=c++1y -S -o - -emit-llvm -verify %s ++ ++namespace default_arg_temporary { ++ ++constexpr bool equals(const float& arg = 1.0f) { ++ return arg == 1.0f; ++} ++ ++constexpr const int &x(const int &p = 0) { ++ return p; ++} ++ ++struct S { ++ constexpr S(const int &a = 0) {} ++}; ++ ++void test_default_arg2() { ++ // This piece of code used to cause an assertion failure in ++ // CallStackFrame::createTemporary because the same MTE is used to initilize ++ // both elements of the array (see PR33140). ++ constexpr S s[2] = {}; ++ ++ // This piece of code used to cause an assertion failure in ++ // CallStackFrame::createTemporary because multiple CXXDefaultArgExpr share ++ // the same MTE (see PR33140). ++ static_assert(equals() && equals(), ""); ++ ++ // Test that constant expression evaluation produces distinct lvalues for ++ // each call. ++ static_assert(&x() != &x(), ""); ++} ++ ++// Check that multiple CXXDefaultInitExprs don't cause an assertion failure. ++struct A { int &&r = 0; }; // expected-warning {{binding reference member}} // expected-note {{reference member declared here}} ++struct B { A x, y; }; ++B b = {}; ++ ++} Property changes on: head/devel/llvm60/files/clang/patch-stable12-r342281.diff ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1,2 ## +yes +\ No newline at end of property \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property