diff --git a/CMakeLists.txt b/CMakeLists.txt index 411be9c9..ab9a9364 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ endif() # find_package(LLVM 3.1 REQUIRED - all-targets bitwriter linker ipo instrumentation backend support tablegen asmparser ${EXTRA_LLVM_MODULES}) + all-targets bitwriter linker ipo instrumentation backend support tablegen asmparser lto ${EXTRA_LLVM_MODULES}) math(EXPR LDC_LLVM_VER ${LLVM_VERSION_MAJOR}*100+${LLVM_VERSION_MINOR}) # diff --git a/cmake/Modules/FindLLVM.cmake b/cmake/Modules/FindLLVM.cmake index 9cc0e380..aabf08d4 100644 --- a/cmake/Modules/FindLLVM.cmake +++ b/cmake/Modules/FindLLVM.cmake @@ -51,6 +51,10 @@ if (WIN32 OR NOT LLVM_CONFIG) list(REMOVE_ITEM LLVM_FIND_COMPONENTS "all-targets" index) list(APPEND LLVM_FIND_COMPONENTS ${LLVM_TARGETS_TO_BUILD}) list(REMOVE_ITEM LLVM_FIND_COMPONENTS "backend" index) + if(${LLVM_VERSION_STRING} MATCHES "3.[0-4][A-Za-z]*") + # Versions below 3.5 do not supoort component lto + list(REMOVE_ITEM LLVM_FIND_COMPONENTS "lto" index) + endif() llvm_map_components_to_libraries(tmplibs ${LLVM_FIND_COMPONENTS}) if(MSVC) @@ -102,6 +106,10 @@ else() endmacro() llvm_set(VERSION_STRING version) + if(${LLVM_VERSION_STRING} MATCHES "3.[0-4][A-Za-z]*") + # Versions below 3.5 do not supoort component lto + list(REMOVE_ITEM LLVM_FIND_COMPONENTS "lto" index) + endif() if(${LLVM_VERSION_STRING} MATCHES "3.0[A-Za-z]*") # Version 3.0 does not support component all-targets llvm_set(TARGETS_TO_BUILD targets-built) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 399509e9..ac203a20 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -1135,8 +1135,24 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun assert((arrty->ty == Tsarray || arrty->ty == Tarray || arrty->ty == Tpointer) && "Can only array bounds check for static or dynamic arrays"); - // static arrays could get static checks for static indices - // but shouldn't since it might be generic code that's never executed + // Do not emit bounds check code if the index is statically known to be + // within bounds. + if (arrty->ty == Tsarray && isaConstantInt(index->getRVal())) { + assert(!arr->isSlice()); + assert(!arr->isNull()); + assert(!lowerBound); + + TypeSArray *sarray = static_cast(arrty); + llvm::ConstantInt *constIndex = static_cast(index->getRVal()); + if (sarray->dim->toUInteger() < constIndex->getZExtValue()) { + // If this happens then it is possible a frontend bug. + // Just output a warning and continue generating a runtime check. + // This could be generic code which is never executed. + warning(loc, "Static array index out of bounds (should have been detected during semantic analysis)"); + } + else + return ; + } // runtime check