Index: flang/CMakeLists.txt =================================================================== --- flang/CMakeLists.txt +++ flang/CMakeLists.txt @@ -2,8 +2,9 @@ set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) -# Flang requires C++17. +# Flang requires C++17 or later. set(CMAKE_CXX_STANDARD 17) +#set(CMAKE_CXX_STANDARD 20) # also works set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_EXTENSIONS OFF) @@ -109,7 +110,7 @@ # avoid some mixed compilation flangs (e.g. -std=c++11 ... -std=c++17). if (DEFINED LLVM_CXX_STD) message("LLVM configuration set a C++ standard: ${LLVM_CXX_STD}") - if (NOT LLVM_CXX_STD EQUAL "c++17") + if (NOT LLVM_CXX_STD EQUAL "c++17" AND NOT LLVM_CXX_STD EQUAL "c++20") message("Flang: Overriding LLVM's 'cxx_std' setting...") message(" removing '-std=${LLVM_CXX_STD}'") message(" CMAKE_CXX_FLAGS='${CMAKE_CXX_FLAGS}'") Index: flang/include/flang/Parser/parse-tree.h =================================================================== --- flang/include/flang/Parser/parse-tree.h +++ flang/include/flang/Parser/parse-tree.h @@ -269,7 +269,8 @@ // A parse tree node with provenance only struct Verbatim { - BOILERPLATE(Verbatim); + COPY_AND_ASSIGN_BOILERPLATE(Verbatim); + constexpr Verbatim() {} using EmptyTrait = std::true_type; CharBlock source; }; Index: flang/lib/Evaluate/check-expression.cpp =================================================================== --- flang/lib/Evaluate/check-expression.cpp +++ flang/lib/Evaluate/check-expression.cpp @@ -173,7 +173,7 @@ return (*this)(x.left()); } template bool operator()(const Expr &x) { - return std::visit([=](const auto &y) { return (*this)(y); }, x.u); + return std::visit([this](const auto &y) { return (*this)(y); }, x.u); } template bool operator()(const A *x) { return x && (*this)(*x); } template bool operator()(const std::optional &x) { Index: flang/lib/Evaluate/host.h =================================================================== --- flang/lib/Evaluate/host.h +++ flang/lib/Evaluate/host.h @@ -80,17 +80,23 @@ } } -// Scalar conversion utilities from F18 scalars to host scalars +// Scalar conversion utilities from F18 scalars to host scalars. template inline constexpr HostType CastFortranToHost(const Scalar &x) { static_assert(HostTypeExists()); - if constexpr (FTN_T::category == TypeCategory::Complex && - sizeof(Scalar) != sizeof(HostType)) { - // X87 is usually padded to 12 or 16bytes. Need to cast piecewise for - // complex - return HostType{CastFortranToHost(x.REAL()), - CastFortranToHost(x.AIMAG())}; + if constexpr (FTN_T::category == TypeCategory::Complex) { + using FortranPartType = typename FTN_T::Part; + return HostType{CastFortranToHost(x.REAL()), + CastFortranToHost(x.AIMAG())}; + } else if constexpr (std::is_same_v>) { + // x87 80-bit floating-point occupies 16 bytes as a C "long double"; + // copy the data to avoid a legitimate (but benign due to little-endianness) + // warning from GCC >= 11.2.0. + HostType y; + std::memcpy(&y, &x, sizeof x); + return y; } else { + static_assert(sizeof x == sizeof(HostType)); return *reinterpret_cast *>(&x); } } Index: flang/lib/Optimizer/CodeGen/TargetRewrite.cpp =================================================================== --- flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -128,14 +128,14 @@ rewriter->create(loc, dyn_cast_ptrEleTy(resTy)); newInTys.push_back(resTy); newOpers.push_back(stack); - return [=](mlir::Operation *) -> mlir::Value { + return [this, loc, stack, ty](mlir::Operation *) -> mlir::Value { auto memTy = ReferenceType::get(ty); auto cast = rewriter->create(loc, memTy, stack); return rewriter->create(loc, cast); }; } newResTys.push_back(resTy); - return [=](mlir::Operation *call) -> mlir::Value { + return [this, loc, resTy, ty](mlir::Operation *call) -> mlir::Value { auto mem = rewriter->create(loc, resTy); rewriter->create(loc, call->getResult(0), mem); auto memTy = ReferenceType::get(ty); @@ -643,10 +643,11 @@ auto argTy = std::get(tup); if (attr.isSRet()) { unsigned argNo = newInTys.size(); - fixups.emplace_back( - FixupTy::Codes::ReturnAsStore, argNo, [=](mlir::FuncOp func) { - func.setArgAttr(argNo, "llvm.sret", rewriter->getUnitAttr()); - }); + fixups.emplace_back(FixupTy::Codes::ReturnAsStore, argNo, + [this, argNo](mlir::FuncOp func) { + func.setArgAttr(argNo, "llvm.sret", + rewriter->getUnitAttr()); + }); newInTys.push_back(argTy); return; } @@ -675,7 +676,8 @@ if (attr.isByVal()) { if (auto align = attr.getAlignment()) fixups.emplace_back( - FixupTy::Codes::ArgumentAsLoad, argNo, [=](mlir::FuncOp func) { + FixupTy::Codes::ArgumentAsLoad, argNo, + [this, align, argNo](mlir::FuncOp func) { func.setArgAttr(argNo, "llvm.byval", rewriter->getUnitAttr()); func.setArgAttr(argNo, "llvm.align", rewriter->getIntegerAttr( @@ -683,17 +685,18 @@ }); else fixups.emplace_back(FixupTy::Codes::ArgumentAsLoad, newInTys.size(), - [=](mlir::FuncOp func) { + [this, argNo](mlir::FuncOp func) { func.setArgAttr(argNo, "llvm.byval", rewriter->getUnitAttr()); }); } else { if (auto align = attr.getAlignment()) - fixups.emplace_back(fixupCode, argNo, index, [=](mlir::FuncOp func) { - func.setArgAttr( - argNo, "llvm.align", - rewriter->getIntegerAttr(rewriter->getIntegerType(32), align)); - }); + fixups.emplace_back( + fixupCode, argNo, index, [this, align, argNo](mlir::FuncOp func) { + func.setArgAttr(argNo, "llvm.align", + rewriter->getIntegerAttr( + rewriter->getIntegerType(32), align)); + }); else fixups.emplace_back(fixupCode, argNo, index); } Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -5242,7 +5242,7 @@ const parser::TypeParamValue &x, common::TypeParamAttr attr) { return std::visit( common::visitors{ - [=](const parser::ScalarIntExpr &x) { // C704 + [this, attr](const parser::ScalarIntExpr &x) { // C704 return ParamValue{EvaluateIntExpr(x), attr}; }, [=](const parser::Star &) { return ParamValue::Assumed(attr); }, @@ -5883,8 +5883,8 @@ const parser::DataRef &x) { return std::visit( common::visitors{ - [=](const parser::Name &y) { return ResolveName(y); }, - [=](const Indirection &y) { + [this](const parser::Name &y) { return ResolveName(y); }, + [this](const Indirection &y) { return ResolveStructureComponent(y.value()); }, [&](const Indirection &y) { @@ -6365,10 +6365,10 @@ for (const auto &accessId : accessIds) { std::visit( common::visitors{ - [=](const parser::Name &y) { + [this, accessAttr](const parser::Name &y) { Resolve(y, SetAccess(y.source, accessAttr)); }, - [=](const Indirection &y) { + [this, accessAttr](const Indirection &y) { auto info{GenericSpecInfo{y.value()}}; const auto &symbolName{info.symbolName()}; if (auto *symbol{FindInScope(symbolName)}) {