@@ -67,3 +67,6 @@ f6d557ee34b6bbdb | |||
# [libc++] Rename _LIBCPP_INLINE_V | # [libc++] Rename _LIBCPP_INLINE_V | ||
4c198542226223f6 | 4c198542226223f6 | ||
+ | |||
+# [libc++] Replace uses of _VSTD:: by std:: (#74331) | |||
+77a00c0d546cd4aa |
@@ -33,26 +33,42 @@ | |||
/lldb/ @JDevlieghere | /lldb/ @JDevlieghere | ||
-/mlir/include/mlir/Interfaces/TilingInterface.* @MaheshRavishanka | +# Linalg in MLIR. | ||
+/mlir/include/mlir/Dialect/Linalg @dcaballe @nicolasvasilache | |||
+/mlir/lib/Dialect/Linalg @dcaballe @nicolasvasilache | |||
-/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgO | +# Vector in MLIR. | ||
-/mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp @MaheshRavishanka | +/mlir/**/*AMX* @dcaballe | ||
-/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFus | +/mlir/**/*Neon* @banach-space @dcaballe @nicolasvasilache | ||
-/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowTyp | +/mlir/**/*SME* @banach-space @dcaballe @nicolasvasilache | ||
-/mlir/lib/Dialect/Vector/Transforms/VectorEmulateNar | +/mlir/**/*SVE* @banach-space @dcaballe @nicolasvasilache | ||
-/mlir/lib/Interfaces/TilingInterface.* @MaheshRavishanka | +/mlir/**/*VectorInterfaces | ||
+/mlir/**/*VectorToSCF* @banach-space @dcaballe @nicolasvasilache | |||
+/mlir/**/*VectorToLLVM* @banach-space @dcaballe @nicolasvasilache | |||
+/mlir/**/*X86Vector* @dcaballe @nicolasvasilache | |||
+/mlir/include/mlir/Dialect/Vector @dcaballe @nicolasvasilache | |||
+/mlir/lib/Dialect/Vector @dcaballe @nicolasvasilache | |||
+ | |||
+/mlir/include/mlir/Interfaces/TilingInterface.* @MaheshRavishanka | |||
+ | |||
+/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgO | |||
+/mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp @MaheshRavishanka | |||
+/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFus | |||
+/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowTyp | |||
+/mlir/lib/Dialect/Vector/Transforms/VectorEmulateNar | |||
+/mlir/lib/Interfaces/TilingInterface.* @MaheshRavishanka | |||
/mlir/**/*EmulateNarrowTyp | /mlir/**/*EmulateNarrowTyp | ||
-/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @hanhanW | +/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @hanhanW @nicolasvasilache | ||
-/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp @hanhanW | +/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp @hanhanW @nicolasvasilache | ||
-/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @hanhanW | +/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @hanhanW @nicolasvasilache | ||
-/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @hanhanW | +/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @hanhanW @nicolasvasilache | ||
-/mlir/lib/Dialect/Tensor/Transforms/FoldIntoPackAndUnpackPatterns.cpp @hanhanW | +/mlir/lib/Dialect/Tensor/Transforms/FoldIntoPackAndUnpackPatterns.cpp @hanhanW @nicolasvasilache | ||
-/mlir/lib/Dialect/Vector/Transforms/* @hanhanW | +/mlir/lib/Dialect/Vector/Transforms/* @hanhanW @nicolasvasilache | ||
# Transform Dialect in MLIR. | # Transform Dialect in MLIR. | ||
-/mlir/include/mlir/Dialect/Transform/* @ftynse | +/mlir/include/mlir/Dialect/Transform/* @ftynse @nicolasvasilache | ||
-/mlir/lib/Dialect/Transform/* @ftynse | +/mlir/lib/Dialect/Transform/* @ftynse @nicolasvasilache | ||
# SPIR-V in MLIR. | # SPIR-V in MLIR. | ||
/mlir/**/SPIRV/ @antiagainst @kuhar | /mlir/**/SPIRV/ @antiagainst @kuhar |
@@ -10,6 +10,11 @@ on: | |||
required: false | required: false | ||
projects: | projects: | ||
required: false | required: false | ||
+ extra_cmake_args | |||
+ required: false | |||
+ os_list: | |||
+ required: false | |||
+ default: '["ubuntu-latest", "windows-2019", "macOS-11"]' | |||
workflow_call: | workflow_call: | ||
inputs: | inputs: | ||
build_target: | build_target: | ||
@@ -20,6 +25,19 @@ on: | |||
required: true | required: true | ||
type: string | type: string | ||
+ extra_cmake_args | |||
+ required: false | |||
+ type: string | |||
+ | |||
+ os_list: | |||
+ required: false | |||
+ type: string | |||
+ # Use windows-2019 due to: | |||
+ # https://developercommuni | |||
+ # We're using a specific version of macOS due to: | |||
+ # https://github.com/actions/virtual-environments/issues/5900 | |||
+ default: '["ubuntu-latest", "windows-2019", "macOS-11"]' | |||
+ | |||
concurrency: | concurrency: | ||
# Skip intermediate builds: always. | # Skip intermediate builds: always. | ||
# Cancel intermediate builds: only if it is a pull request build. | # Cancel intermediate builds: only if it is a pull request build. | ||
@@ -35,14 +53,7 @@ jobs: | |||
strategy: | strategy: | ||
fail-fast: false | fail-fast: false | ||
matrix: | matrix: | ||
- os: | + os: ${{ fromJSON(inputs.os_list) }} | ||
- - ubuntu-latest | |||
- # Use windows-2019 due to: | |||
- # https://developercommuni | |||
- - windows-2019 | |||
- # We're using a specific version of macOS due to: | |||
- # https://github.com/actions/virtual-environments/issues/5900 | |||
- - macOS-11 | |||
steps: | steps: | ||
- name: Setup Windows | - name: Setup Windows | ||
if: startsWith(matrix.os, 'windows') | if: startsWith(matrix.os, 'windows') | ||
@@ -85,7 +96,7 @@ jobs: | |||
# This should be a no-op for non-mac OSes | # This should be a no-op for non-mac OSes | ||
PKG_CONFIG_PATH: /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig//12 | PKG_CONFIG_PATH: /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig//12 | ||
with: | with: | ||
- cmake_args: '-GNinja -DLLVM_ENABLE_PROJECTS="${{ inputs.projects }}" -DCMAKE_BUILD_TYPE=Release -DLLDB_INCLUDE_TESTS=OFF -DCMAKE_C_COMPILER_LAUNCHER=sccache - | + cmake_args: '-GNinja -DLLVM_ENABLE_PROJECTS="${{ inputs.projects }}" -DCMAKE_BUILD_TYPE=Release -DLLDB_INCLUDE_TESTS=OFF -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache ${{ inputs.extra_cmake_args }}' | ||
build_target: '${{ inputs.build_target }}' | build_target: '${{ inputs.build_target }}' | ||
- name: Build and Test libclc | - name: Build and Test libclc |
@@ -0,0 +1,29 @@ | |||
+name: SPIR-V Tests | |||
+ | |||
+permissions: | |||
+ contents: read | |||
+ | |||
+on: | |||
+ workflow_dispatc | |||
+ pull_request: | |||
+ paths: | |||
+ - 'llvm/lib/Target/SPIRV/**' | |||
+ - 'llvm/test/CodeGen/SPIRV/**' | |||
+ - '.github/workflows/spirv-tests.yml' | |||
+ | |||
+concurrency: | |||
+ # Skip intermediate builds: always. | |||
+ # Cancel intermediate builds: only if it is a pull request build. | |||
+ group: ${{ github.workflow }}-${{ github.ref }} | |||
+ cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} | |||
+ | |||
+jobs: | |||
+ check_spirv: | |||
+ if: github.repository_owner | |||
+ name: Test SPIR-V | |||
+ uses: ./.github/workflows/llvm-project-tests.yml | |||
+ with: | |||
+ build_target: check-llvm-codegen-spirv | |||
+ projects: | |||
+ extra_cmake_args | |||
+ os_list: '["ubuntu-latest"]' |
@@ -33,6 +33,8 @@ | |||
<qiucofan@cn.ibm.com> <qiucf@cn.ibm.com> | <qiucofan@cn.ibm.com> <qiucf@cn.ibm.com> | ||
<rnk@google.com> <reid@kleckner.net> | <rnk@google.com> <reid@kleckner.net> | ||
<thakis@chromium.org> <nicolasweber@gmx.de> | <thakis@chromium.org> <nicolasweber@gmx.de> | ||
+Jianjian GUAN <jacquesguan@me.com> | |||
+Jianjian GUAN <jacquesguan@me.com> <Jianjian.Guan@streamcomputing.com> | |||
Jon Roelofs <jonathan_roelofs | Jon Roelofs <jonathan_roelofs | ||
Jon Roelofs <jonathan_roelofs | Jon Roelofs <jonathan_roelofs | ||
Jonathan Thackray <jonathan.thackray@arm.com> <jthackray@users.noreply.github.com> | Jonathan Thackray <jonathan.thackray@arm.com> <jthackray@users.noreply.github.com> |
@@ -133,6 +133,21 @@ UnusedReturnValu | |||
"::boost::system::error_code"))), | "::boost::system::error_code"))), | ||
AllowCastToVoid(Options.get("AllowCastToVoid", false)) {} | AllowCastToVoid(Options.get("AllowCastToVoid", false)) {} | ||
+UnusedReturnValu | |||
+ ClangTidyContext | |||
+ std::string CheckedFunctions | |||
+ : UnusedReturnValu | |||
+ false) {} | |||
+ | |||
+UnusedReturnValu | |||
+ llvm::StringRef Name, ClangTidyContext | |||
+ std::string CheckedFunctions | |||
+ bool AllowCastToVoid) | |||
+ : ClangTidyCheck(Name, Context), | |||
+ CheckedFunctions | |||
+ CheckedReturnTyp | |||
+ AllowCastToVoid(AllowCastToVoid) {} | |||
+ | |||
void UnusedReturnValu | void UnusedReturnValu | ||
Options.store(Opts, "CheckedFunctions | Options.store(Opts, "CheckedFunctions | ||
Options.store(Opts, "CheckedReturnTyp | Options.store(Opts, "CheckedReturnTyp |
@@ -31,7 +31,15 @@ public: | |||
private: | private: | ||
std::string CheckedFunctions | std::string CheckedFunctions | ||
const std::vector<StringRef> CheckedReturnTyp | const std::vector<StringRef> CheckedReturnTyp | ||
- const bool AllowCastToVoid; | + | ||
+protected: | |||
+ UnusedReturnValu | |||
+ std::string CheckedFunctions | |||
+ UnusedReturnValu | |||
+ std::string CheckedFunctions | |||
+ std::vector<StringRef> CheckedReturnTyp | |||
+ bool AllowCastToVoid); | |||
+ bool AllowCastToVoid; | |||
}; | }; | ||
} // namespace clang::tidy::bugprone | } // namespace clang::tidy::bugprone |
@@ -6,6 +6,7 @@ set(LLVM_LINK_CO | |||
add_clang_librar | add_clang_librar | ||
ExceptionBasecla | ExceptionBasecla | ||
HICPPTidyModule.cpp | HICPPTidyModule.cpp | ||
+ IgnoredRemoveRes | |||
MultiwayPathsCov | MultiwayPathsCov | ||
NoAssemblerCheck | NoAssemblerCheck | ||
SignedBitwiseChe | SignedBitwiseChe |
@@ -37,6 +37,7 @@ | |||
#include "../readability/NamedParameterCh | #include "../readability/NamedParameterCh | ||
#include "../readability/UppercaseLiteral | #include "../readability/UppercaseLiteral | ||
#include "ExceptionBasecla | #include "ExceptionBasecla | ||
+#include "IgnoredRemoveRes | |||
#include "MultiwayPathsCov | #include "MultiwayPathsCov | ||
#include "NoAssemblerCheck | #include "NoAssemblerCheck | ||
#include "SignedBitwiseChe | #include "SignedBitwiseChe | ||
@@ -57,6 +58,8 @@ public: | |||
"hicpp-deprecated-headers"); | "hicpp-deprecated-headers"); | ||
CheckFactories.registerCheck<ExceptionBasecla | CheckFactories.registerCheck<ExceptionBasecla | ||
"hicpp-exception-baseclass"); | "hicpp-exception-baseclass"); | ||
+ CheckFactories.registerCheck<IgnoredRemoveRes | |||
+ "hicpp-ignored-remove-result"); | |||
CheckFactories.registerCheck<MultiwayPathsCov | CheckFactories.registerCheck<MultiwayPathsCov | ||
"hicpp-multiway-paths-covered"); | "hicpp-multiway-paths-covered"); | ||
CheckFactories.registerCheck<SignedBitwiseChe | CheckFactories.registerCheck<SignedBitwiseChe |
@@ -0,0 +1,28 @@ | |||
+//===--- IgnoredRemoveRes | |||
+// | |||
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
+// See https://llvm.org/LICENSE.txt for license information. | |||
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
+// | |||
+//===----------------------------------------------------------------------===// | |||
+ | |||
+#include "IgnoredRemoveRes | |||
+ | |||
+namespace clang::tidy::hicpp { | |||
+ | |||
+IgnoredRemoveRes | |||
+ ClangTidyContext | |||
+ : UnusedReturnValu | |||
+ "::std::remove;" | |||
+ "::std::remove_if;" | |||
+ "::std::unique") { | |||
+ // The constructor for ClangTidyCheck needs to have been called | |||
+ // before we can access options via Options.get(). | |||
+ AllowCastToVoid = Options.get("AllowCastToVoid", true); | |||
+} | |||
+ | |||
+void IgnoredRemoveRes | |||
+ Options.store(Opts, "AllowCastToVoid", AllowCastToVoid); | |||
+} | |||
+ | |||
+} // namespace clang::tidy::hicpp |
@@ -0,0 +1,29 @@ | |||
+//===--- IgnoredRemoveRes | |||
+// | |||
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
+// See https://llvm.org/LICENSE.txt for license information. | |||
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
+// | |||
+//===----------------------------------------------------------------------===// | |||
+ | |||
+#ifndef LLVM_CLANG_TOOLS | |||
+#define LLVM_CLANG_TOOLS | |||
+ | |||
+#include "../bugprone/UnusedReturnValu | |||
+ | |||
+namespace clang::tidy::hicpp { | |||
+ | |||
+/// Ensure that the result of std::remove, std::remove_if and std::unique | |||
+/// are not ignored according to rule 17.5.1. | |||
+/// | |||
+/// For the user-facing documentation see: | |||
+/// http://clang.llvm.org/extra/clang-tidy/checks/hicpp/ignored-remove-result.html | |||
+class IgnoredRemoveRes | |||
+public: | |||
+ IgnoredRemoveRes | |||
+ void storeOptions(ClangTidyOptions | |||
+}; | |||
+ | |||
+} // namespace clang::tidy::hicpp | |||
+ | |||
+#endif // LLVM_CLANG_TOOLS |
@@ -15,6 +15,7 @@ | |||
#include "clang/AST/Decl.h" | #include "clang/AST/Decl.h" | ||
#include "clang/Basic/Diagnostic.h" | #include "clang/Basic/Diagnostic.h" | ||
#include <optional> | #include <optional> | ||
+#include <utility> | |||
namespace clang::tidy::performance { | namespace clang::tidy::performance { | ||
namespace { | namespace { | ||
@@ -263,19 +264,25 @@ void UnnecessaryCopyI | |||
void UnnecessaryCopyI | void UnnecessaryCopyI | ||
const MatchFinder::MatchResult &Result) { | const MatchFinder::MatchResult &Result) { | ||
- const auto | + const auto &NewVar = *Result.Nodes.getNodeAs<VarDecl>("newVarDecl"); | ||
+ const auto &BlockStmt = *Result.Nodes.getNodeAs<Stmt>("blockStmt"); | |||
+ const auto &VarDeclStmt = *Result.Nodes.getNodeAs<DeclStmt>("declStmt"); | |||
+ // Do not propose fixes if the DeclStmt has multiple VarDecls or in | |||
+ // macros since we cannot place them correctly. | |||
+ const bool IssueFix = | |||
+ VarDeclStmt.isSingleDecl() && !NewVar.getLocation().isMacroID(); | |||
+ const bool IsVarUnused = isVariableUnused | |||
+ const bool IsVarOnlyUsedAsC | |||
+ isOnlyUsedAsCons | |||
+ const CheckContext Context{ | |||
+ NewVar, BlockStmt, VarDeclStmt, *Result.Context, | |||
+ IssueFix, IsVarUnused, IsVarOnlyUsedAsC | |||
const auto *OldVar = Result.Nodes.getNodeAs<VarDecl>(OldVarDeclId); | const auto *OldVar = Result.Nodes.getNodeAs<VarDecl>(OldVarDeclId); | ||
const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(ObjectArgId); | const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(ObjectArgId); | ||
- const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt"); | |||
const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr | const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr | ||
- const auto *Stmt = Result.Nodes.getNodeAs<DeclStmt>("declStmt"); | |||
TraversalKindSco | TraversalKindSco | ||
- // Do not propose fixes if the DeclStmt has multiple VarDecls or in macros | |||
- // since we cannot place them correctly. | |||
- bool IssueFix = Stmt->isSingleDecl() && !NewVar->getLocation().isMacroID(); | |||
- | |||
// A constructor that looks like T(const T& t, bool arg = false) counts as a | // A constructor that looks like T(const T& t, bool arg = false) counts as a | ||
// copy only when it is called with default arguments for the arguments after | // copy only when it is called with default arguments for the arguments after | ||
// the first. | // the first. | ||
@@ -289,74 +296,71 @@ void UnnecessaryCopyI | |||
// instantiations where the types differ and rely on implicit conversion would | // instantiations where the types differ and rely on implicit conversion would | ||
// no longer compile if we switched to a reference. | // no longer compile if we switched to a reference. | ||
if (differentReplace | if (differentReplace | ||
- | + Context.Var.getType(), constructorArgumentType(OldVar, Result.Nodes), | ||
*Result.Context)) | *Result.Context)) | ||
return; | return; | ||
if (OldVar == nullptr) { | if (OldVar == nullptr) { | ||
- handleCopyFromMe | + // `auto NewVar = functionCall();` | ||
- *Result.Context); | + handleCopyFromMe | ||
} else { | } else { | ||
- handleCopyFromLo | + // `auto NewVar = OldVar;` | ||
- *Result.Context); | + handleCopyFromLo | ||
} | } | ||
} | } | ||
void UnnecessaryCopyI | void UnnecessaryCopyI | ||
- const VarDecl &Var, const Stmt &BlockStmt, const DeclStmt &Stmt, | + const CheckContext &Ctx, const VarDecl *ObjectArg) { | ||
- bool IssueFix, const VarDecl *ObjectArg, ASTContext &Context) { | + bool IsConstQualified | ||
- bool IsConstQualified | + if (!IsConstQualified | ||
- if (!IsConstQualified | |||
return; | return; | ||
if (ObjectArg != nullptr && | if (ObjectArg != nullptr && | ||
- !isInitializingVariableImmutable(*ObjectArg, BlockStmt, | + !isInitializingVariableImmutable(*ObjectArg, Ctx.BlockStmt, Ctx.ASTCtx, | ||
ExcludedContaine | ExcludedContaine | ||
return; | return; | ||
- if (isVariableUnused | + diagnoseCopyFrom | ||
- auto Diagnostic = | |||
- diag(Var.getLocation(), | |||
- "the %select{|const qualified }0variable %1 is copy-constructed " | |||
- "from a const reference but is never used; consider " | |||
- "removing the statement") | |||
- << IsConstQualified | |||
- if (IssueFix) | |||
- recordRemoval(Stmt, Context, Diagnostic); | |||
- } else { | |||
- auto Diagnostic = | |||
- diag(Var.getLocation(), | |||
- "the %select{|const qualified }0variable %1 is copy-constructed " | |||
- "from a const reference%select{ but is only used as const " | |||
- "reference|}0; consider making it a const reference") | |||
- << IsConstQualified | |||
- if (IssueFix) | |||
- recordFixes(Var, Context, Diagnostic); | |||
- } | |||
} | } | ||
void UnnecessaryCopyI | void UnnecessaryCopyI | ||
- const VarDecl &NewVar, const VarDecl &OldVar, const Stmt &BlockStmt, | + const CheckContext &Ctx, const VarDecl &OldVar) { | ||
- const DeclStmt &Stmt, bool IssueFix, ASTContext &Context) { | + if (!Ctx.IsVarOnlyUsedAsC | ||
- if (!isOnlyUsedAsCons | + !isInitializingVa | ||
- !isInitializingVa | |||
ExcludedContaine | ExcludedContaine | ||
return; | return; | ||
+ diagnoseCopyFrom | |||
+} | |||
- if (isVariableUnused | +void UnnecessaryCopyI | ||
- auto Diagnostic = diag(NewVar.getLocation(), | + const CheckContext &Ctx) { | ||
- "local copy %0 of the variable %1 is never modified " | + auto Diagnostic = | ||
- "and never used; " | + diag(Ctx.Var.getLocation(), | ||
- "consider removing the statement") | + "the %select{|const qualified }0variable %1 is " | ||
- << &NewVar << &OldVar; | + "copy-constructed " | ||
- if (IssueFix) | + "from a const reference%select{%select{ but is only used as const " | ||
- recordRemoval(Stmt, Context, Diagnostic); | + "reference|}0| but is never used}2; consider " | ||
- } else { | + "%select{making it a const reference|removing the statement}2") | ||
- auto Diagnostic = | + << Ctx.Var.getType().isConstQualified | ||
- diag(NewVar.getLocation(), | + maybeIssueFixes(Ctx, Diagnostic); | ||
- "local copy %0 of the variable %1 is never modified; " | +} | ||
- "consider avoiding the copy") | + | ||
- << &NewVar << &OldVar; | +void UnnecessaryCopyI | ||
- if (IssueFix) | + const CheckContext &Ctx, const VarDecl &OldVar) { | ||
- recordFixes(NewVar, Context, Diagnostic); | + auto Diagnostic = | ||
+ diag(Ctx.Var.getLocation(), | |||
+ "local copy %1 of the variable %0 is never modified%select{" | |||
+ "| and never used}2; consider %select{avoiding the copy|removing " | |||
+ "the statement}2") | |||
+ << &OldVar << &Ctx.Var << Ctx.IsVarUnused; | |||
+ maybeIssueFixes(Ctx, Diagnostic); | |||
+} | |||
+ | |||
+void UnnecessaryCopyI | |||
+ const CheckContext &Ctx, DiagnosticBuilde | |||
+ if (Ctx.IssueFix) { | |||
+ if (Ctx.IsVarUnused) | |||
+ recordRemoval(Ctx.VarDeclStmt, Ctx.ASTCtx, Diagnostic); | |||
+ else | |||
+ recordFixes(Ctx.Var, Ctx.ASTCtx, Diagnostic); | |||
} | } | ||
} | } | ||
@@ -32,14 +32,32 @@ public: | |||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | ||
void storeOptions(ClangTidyOptions | void storeOptions(ClangTidyOptions | ||
+protected: | |||
+ // A helper to manipulate the state common to | |||
+ // `CopyFromMethodRe | |||
+ struct CheckContext { | |||
+ const VarDecl &Var; | |||
+ const Stmt &BlockStmt; | |||
+ const DeclStmt &VarDeclStmt; | |||
+ clang::ASTContext &ASTCtx; | |||
+ const bool IssueFix; | |||
+ const bool IsVarUnused; | |||
+ const bool IsVarOnlyUsedAsC | |||
+ }; | |||
+ | |||
+ // Create diagnostics. These are virtual so that derived classes can change | |||
+ // behaviour. | |||
+ virtual void diagnoseCopyFrom | |||
+ virtual void diagnoseCopyFrom | |||
+ const VarDecl &OldVar); | |||
+ | |||
private: | private: | ||
- void handleCopyFromMethodReturn(const | + void handleCopyFromMethodReturn(const CheckContext &Ctx, | ||
- const | + const VarDecl *ObjectArg); | ||
- const VarDecl *ObjectArg, | + void handleCopyFromLo | ||
- ASTContext &Context); | + | ||
- void handleCopyFromLo | + void maybeIssueFixes(const CheckContext &Ctx, DiagnosticBuilde | ||
- const Stmt &BlockStmt, const DeclStmt &Stmt, | + | ||
- bool IssueFix, ASTContext &Context); | |||
const std::vector<StringRef> AllowedTypes; | const std::vector<StringRef> AllowedTypes; | ||
const std::vector<StringRef> ExcludedContaine | const std::vector<StringRef> ExcludedContaine | ||
}; | }; |
@@ -174,6 +174,12 @@ New checks | |||
Flags coroutines that suspend while a lock guard is in scope at the | Flags coroutines that suspend while a lock guard is in scope at the | ||
suspension point. | suspension point. | ||
+- New :doc:`hicpp-ignored-remove-result | |||
+ <clang-tidy/checks/hicpp/ignored-remove-result>` check. | |||
+ | |||
+ Ensure that the result of ``std::remove``, ``std::remove_if`` and | |||
+ ``std::unique`` are not ignored according to rule 17.5.1. | |||
+ | |||
- New :doc:`misc-coroutine-hostile-raii | - New :doc:`misc-coroutine-hostile-raii | ||
<clang-tidy/checks/misc/coroutine-hostile-raii>` check. | <clang-tidy/checks/misc/coroutine-hostile-raii>` check. | ||
@@ -0,0 +1,24 @@ | |||
+.. title:: clang-tidy - hicpp-ignored-remove-result | |||
+ | |||
+hicpp-ignored-remove-result | |||
+=========================== | |||
+ | |||
+Ensure that the result of ``std::remove``, ``std::remove_if`` and ``std::unique`` | |||
+are not ignored according to | |||
+`rule 17.5.1 <https://www.perforce.com/resources/qac/high-integrity-cpp-coding-standard/standard-library>`_. | |||
+ | |||
+The mutating algorithms ``std::remove``, ``std::remove_if`` and both overloads | |||
+of ``std::unique`` operate by swapping or moving elements of the range they are | |||
+operating over. On completion, they return an iterator to the last valid | |||
+element. In the majority of cases the correct behavior is to use this result as | |||
+the first operand in a call to ``std::erase``. | |||
+ | |||
+This check is a subset of :doc:`bugprone-unused-return-value <../bugprone/unused-return-value>` | |||
+and depending on used options it can be superfluous to enable both checks. | |||
+ | |||
+Options | |||
+------- | |||
+ | |||
+.. option:: AllowCastToVoid | |||
+ | |||
+ Controls whether casting return values to ``void`` is permitted. Default: `true`. |
@@ -226,6 +226,7 @@ Clang-Tidy Checks | |||
:doc:`google-runtime-operator <google/runtime-operator>`, | :doc:`google-runtime-operator <google/runtime-operator>`, | ||
:doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes" | :doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes" | ||
:doc:`hicpp-exception-baseclass <hicpp/exception-baseclass>`, | :doc:`hicpp-exception-baseclass <hicpp/exception-baseclass>`, | ||
+ :doc:`hicpp-ignored-remove-result <hicpp/ignored-remove-result>`, | |||
:doc:`hicpp-multiway-paths-covered <hicpp/multiway-paths-covered>`, | :doc:`hicpp-multiway-paths-covered <hicpp/multiway-paths-covered>`, | ||
:doc:`hicpp-no-assembler <hicpp/no-assembler>`, | :doc:`hicpp-no-assembler <hicpp/no-assembler>`, | ||
:doc:`hicpp-signed-bitwise <hicpp/signed-bitwise>`, | :doc:`hicpp-signed-bitwise <hicpp/signed-bitwise>`, |
@@ -0,0 +1,66 @@ | |||
+// RUN: %check_clang_tidy | |||
+// RUN: %check_clang_tidy | |||
+ | |||
+namespace std { | |||
+ | |||
+template <typename ForwardIt, typename T> | |||
+ForwardIt remove(ForwardIt, ForwardIt, const T &); | |||
+ | |||
+template <typename ForwardIt, typename UnaryPredicate> | |||
+ForwardIt remove_if(ForwardIt, ForwardIt, UnaryPredicate); | |||
+ | |||
+template <typename ForwardIt> | |||
+ForwardIt unique(ForwardIt, ForwardIt); | |||
+ | |||
+template <class InputIt, class T> | |||
+InputIt find(InputIt, InputIt, const T&); | |||
+ | |||
+class error_code { | |||
+}; | |||
+ | |||
+} // namespace std | |||
+ | |||
+std::error_code errorFunc() { | |||
+ return std::error_code(); | |||
+} | |||
+ | |||
+void warning() { | |||
+ std::remove(nullptr, nullptr, 1); | |||
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+ // CHECK-MESSAGES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning | |||
+ // CHECK-MESSAGES-NOCAST: [[@LINE-3]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+ | |||
+ std::remove_if(nullptr, nullptr, nullptr); | |||
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+ // CHECK-MESSAGES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning | |||
+ // CHECK-MESSAGES-NOCAST: [[@LINE-3]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+ | |||
+ std::unique(nullptr, nullptr); | |||
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+ // CHECK-MESSAGES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning | |||
+ // CHECK-MESSAGES-NOCAST: [[@LINE-3]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+} | |||
+ | |||
+void optionalWarning() { | |||
+ // No warning unless AllowCastToVoid=false | |||
+ (void)std::remove(nullptr, nullptr, 1); | |||
+ // CHECK-MESSAGES-NOCAST: [[@LINE-1]]:9: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors | |||
+} | |||
+ | |||
+void noWarning() { | |||
+ | |||
+ auto RemoveRetval = std::remove(nullptr, nullptr, 1); | |||
+ | |||
+ auto RemoveIfRetval = std::remove_if(nullptr, nullptr, nullptr); | |||
+ | |||
+ auto UniqueRetval = std::unique(nullptr, nullptr); | |||
+ | |||
+ // Verify that other checks in the baseclass are not used. | |||
+ // - no warning on std::find since the checker overrides | |||
+ // bugprone-unused-return-value's checked functions. | |||
+ std::find(nullptr, nullptr, 1); | |||
+ // - no warning on return types since the checker disable | |||
+ // bugprone-unused-return-value's checked return types. | |||
+ errorFunc(); | |||
+ (void) errorFunc(); | |||
+} |
@@ -1483,6 +1483,7 @@ Conditional ``explicit`` __cpp_conditiona | |||
``using enum`` __cpp_using_enum | ``using enum`` __cpp_using_enum | ||
``if consteval`` __cpp_if_constev | ``if consteval`` __cpp_if_constev | ||
``static operator()`` __cpp_static_cal | ``static operator()`` __cpp_static_cal | ||
+Attributes on Lambda-Expressions C++23 C++11 | |||
-------------------------------------- -------------------------------- ------------- ------------- | -------------------------------------- -------------------------------- ------------- ------------- | ||
Designated initializers (N494) C99 C89 | Designated initializers (N494) C99 C89 | ||
Array & element qualification (N2607) C23 C89 | Array & element qualification (N2607) C23 C89 | ||
@@ -3866,6 +3867,30 @@ builtin function, and are named with a ``__opencl_`` prefix. The macros | |||
and ``__OPENCL_MEMORY_ | and ``__OPENCL_MEMORY_ | ||
corresponding to the enumerators of OpenCL's ``memory_scope`` enumeration.) | corresponding to the enumerators of OpenCL's ``memory_scope`` enumeration.) | ||
+__scoped_atomic builtins | |||
+------------------------ | |||
+ | |||
+Clang provides a set of atomics taking a memory scope argument. These atomics | |||
+are identical to the standard GNU / GCC atomic builtins but taking an extra | |||
+memory scope argument. These are designed to be a generic alternative to the | |||
+``__opencl_atomic_ | |||
+scopes. | |||
+ | |||
+Atomic memory scopes are designed to assist optimizations for systems with | |||
+several levels of memory hierarchy like GPUs. The following memory scopes are | |||
+currently supported: | |||
+ | |||
+* ``__MEMORY_SCOPE_S | |||
+* ``__MEMORY_SCOPE_D | |||
+* ``__MEMORY_SCOPE_W | |||
+* ``__MEMORY_SCOPE_W | |||
+* ``__MEMORY_SCOPE_S | |||
+ | |||
+This controls whether or not the atomic operation is ordered with respect to the | |||
+whole system, the current device, an OpenCL workgroup, wavefront, or just a | |||
+single thread. If these are used on a target that does not support atomic | |||
+scopes, then they will behave exactly as the standard GNU atomic builtins. | |||
+ | |||
Low-level ARM exclusive memory builtins | Low-level ARM exclusive memory builtins | ||
--------------------------------------- | --------------------------------------- | ||
@@ -156,6 +156,9 @@ C++23 Feature Support | |||
support for this feature is still experimental, the feature test macro ``__cpp_explicit_t | support for this feature is still experimental, the feature test macro ``__cpp_explicit_t | ||
was not set in this version. | was not set in this version. | ||
+- Added a separate warning to warn the use of attributes on lambdas as a C++23 extension | |||
+ in previous language versions: ``-Wc++23-lambda-attributes``. | |||
+ | |||
C++2c Feature Support | C++2c Feature Support | ||
^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^ | ||
@@ -201,6 +204,9 @@ C Language Changes | |||
number of elements in the flexible array member. This information can improve | number of elements in the flexible array member. This information can improve | ||
the results of the array bound sanitizer and the | the results of the array bound sanitizer and the | ||
``__builtin_dynami | ``__builtin_dynami | ||
+- Enums will now be represented in TBAA metadata using their actual underlying | |||
+ integer type. Previously they were treated as chars, which meant they could | |||
+ alias with all other types. | |||
C23 Feature Support | C23 Feature Support | ||
^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^ | ||
@@ -353,6 +359,8 @@ Improvements to Clang's diagnostics | |||
of a base class is not called in the constructor of its derived class. | of a base class is not called in the constructor of its derived class. | ||
- Clang no longer emits ``-Wmissing-variable-declarations`` for variables declared | - Clang no longer emits ``-Wmissing-variable-declarations`` for variables declared | ||
with the ``register`` storage class. | with the ``register`` storage class. | ||
+- Clang's ``-Wswitch-default`` flag now diagnoses whenever a ``switch`` statement | |||
+ does not have a ``default`` label. | |||
- Clang's ``-Wtautological-negation-compare`` flag now diagnoses logical | - Clang's ``-Wtautological-negation-compare`` flag now diagnoses logical | ||
tautologies like ``x && !x`` and ``!x || x`` in expressions. This also | tautologies like ``x && !x`` and ``!x || x`` in expressions. This also | ||
makes ``-Winfinite-recursion`` diagnose more cases. | makes ``-Winfinite-recursion`` diagnose more cases. | ||
@@ -651,6 +659,9 @@ Bug Fixes in This Version | |||
- Fixed false positive error emitted by clang when performing qualified name | - Fixed false positive error emitted by clang when performing qualified name | ||
lookup and the current class instantiation has dependent bases. | lookup and the current class instantiation has dependent bases. | ||
Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_) | Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_) | ||
+- Fix a ``clang-17`` regression where a templated friend with constraints is not | |||
+ properly applied when its parameters reference an enclosing non-template class. | |||
+ Fixes (`#71595 <https://github.com/llvm/llvm-project/issues/71595>`_) | |||
- Fix the name of the ifunc symbol emitted for multiversion functions declared with the | - Fix the name of the ifunc symbol emitted for multiversion functions declared with the | ||
``target_clones`` attribute. This addresses a linker error that would otherwise occur | ``target_clones`` attribute. This addresses a linker error that would otherwise occur | ||
when these functions are referenced from other TUs. | when these functions are referenced from other TUs. | ||
@@ -658,6 +669,12 @@ Bug Fixes in This Version | |||
Fixes (`#64467 <https://github.com/llvm/llvm-project/issues/64467>`_) | Fixes (`#64467 <https://github.com/llvm/llvm-project/issues/64467>`_) | ||
- Clang's ``-Wchar-subscripts`` no longer warns on chars whose values are known non-negative constants. | - Clang's ``-Wchar-subscripts`` no longer warns on chars whose values are known non-negative constants. | ||
Fixes (`#18763 <https://github.com/llvm/llvm-project/issues/18763>`_) | Fixes (`#18763 <https://github.com/llvm/llvm-project/issues/18763>`_) | ||
+- Fix crash due to incorrectly allowing conversion functions in copy elision. | |||
+ Fixes (`#39319 <https://github.com/llvm/llvm-project/issues/39319>`_) and | |||
+ (`#60182 <https://github.com/llvm/llvm-project/issues/60182>`_) and | |||
+ (`#62157 <https://github.com/llvm/llvm-project/issues/62157>`_) and | |||
+ (`#64885 <https://github.com/llvm/llvm-project/issues/64885>`_) and | |||
+ (`#65568 <https://github.com/llvm/llvm-project/issues/65568>`_) | |||
Bug Fixes to Compiler Builtins | Bug Fixes to Compiler Builtins | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
@@ -886,11 +903,17 @@ Arm and AArch64 Support | |||
- New AArch64 asm constraints have been added for r8-r11(Uci) and r12-r15(Ucj). | - New AArch64 asm constraints have been added for r8-r11(Uci) and r12-r15(Ucj). | ||
- | +- Support has been added for the following processors (-mcpu identifiers in parenthesis): | ||
+ | |||
+ For Arm: | |||
+ | |||
+ * Cortex-M52 (cortex-m52). | |||
+ | |||
+ For AArch64: | |||
- * | + * Cortex-A520 (cortex-a520). | ||
- * | + * Cortex-A720 (cortex-a720). | ||
- * | + * Cortex-X4 (cortex-x4). | ||
Android Support | Android Support | ||
^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^ |
@@ -6498,7 +6498,7 @@ public: | |||
return cast<Expr>(SubExprs[ORDER_FAIL]); | return cast<Expr>(SubExprs[ORDER_FAIL]); | ||
} | } | ||
Expr *getVal2() const { | Expr *getVal2() const { | ||
- if (Op == AO__atomic_exchange) | + if (Op == AO__atomic_exchange || Op == AO__scoped_atomic_exchange) | ||
return cast<Expr>(SubExprs[ORDER_FAIL]); | return cast<Expr>(SubExprs[ORDER_FAIL]); | ||
assert(NumSubExprs > VAL2); | assert(NumSubExprs > VAL2); | ||
return cast<Expr>(SubExprs[VAL2]); | return cast<Expr>(SubExprs[VAL2]); | ||
@@ -6539,7 +6539,9 @@ public: | |||
getOp() == AO__opencl_atomi | getOp() == AO__opencl_atomi | ||
getOp() == AO__hip_atomic_c | getOp() == AO__hip_atomic_c | ||
getOp() == AO__atomic_compa | getOp() == AO__atomic_compa | ||
- getOp() == | + getOp() == AO__atomic_compare_exchange_n || | ||
+ getOp() == AO__scoped_atomi | |||
+ getOp() == AO__scoped_atomi | |||
} | } | ||
bool isOpenCL() const { | bool isOpenCL() const { | ||
@@ -6569,13 +6571,13 @@ public: | |||
/// \return empty atomic scope model if the atomic op code does not have | /// \return empty atomic scope model if the atomic op code does not have | ||
/// scope operand. | /// scope operand. | ||
static std::unique_ptr<AtomicScopeModel | static std::unique_ptr<AtomicScopeModel | ||
- auto Kind = | + if (Op >= AO__opencl_atomi | ||
- (Op >= AO__opencl_atomi | + return AtomicScopeModel | ||
- ? AtomicScopeModel | + else if (Op >= AO__hip_atomic_l | ||
- : (Op >= AO__hip_atomic_l | + return AtomicScopeModel | ||
- ? AtomicScopeModel | + else if (Op >= AO__scoped_atomi | ||
- : AtomicScopeModel | + return AtomicScopeModel | ||
- return AtomicScopeModel::create( | + return AtomicScopeModel::create(AtomicScopeModelKind::None); | ||
} | } | ||
/// Get atomic scope model. | /// Get atomic scope model. |
@@ -2659,8 +2659,9 @@ An error will be given if: | |||
- Specified values violate subtarget specifications; | - Specified values violate subtarget specifications; | ||
- Specified values are not compatible with values provided through other | - Specified values are not compatible with values provided through other | ||
attributes; | attributes; | ||
- - The AMDGPU target backend is unable to create machine code that can meet the | + | ||
- request. | +The AMDGPU target backend will emit a warning whenever it is unable to | ||
+create machine code that meets the request. | |||
}]; | }]; | ||
} | } | ||
@@ -904,6 +904,32 @@ BUILTIN(__atomic | |||
BUILTIN(__atomic_always_ | BUILTIN(__atomic_always_ | ||
BUILTIN(__atomic_is_lock | BUILTIN(__atomic_is_lock | ||
+// GNU atomic builtins with atomic scopes. | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ATOMIC_BUILTIN(__scoped_atomic_ | |||
+ | |||
// OpenCL 2.0 atomic builtins. | // OpenCL 2.0 atomic builtins. | ||
ATOMIC_BUILTIN(__opencl_atomic_ | ATOMIC_BUILTIN(__opencl_atomic_ | ||
ATOMIC_BUILTIN(__opencl_atomic_ | ATOMIC_BUILTIN(__opencl_atomic_ |
@@ -80,6 +80,7 @@ def remark_fe_backen | |||
"the '__restrict__' qualifier with the independent array arguments. " | "the '__restrict__' qualifier with the independent array arguments. " | ||
"Erroneous results will occur if these options are incorrectly applied!">, | "Erroneous results will occur if these options are incorrectly applied!">, | ||
BackendInfo, InGroup<BackendOptimizat | BackendInfo, InGroup<BackendOptimizat | ||
+ | |||
def warn_fe_backend_ | def warn_fe_backend_ | ||
InGroup<BackendOptimizat | InGroup<BackendOptimizat | ||
def note_fe_backend_ | def note_fe_backend_ |
@@ -632,7 +632,7 @@ def ShadowAll : DiagGroup<"shado | |||
def Shorten64To32 : DiagGroup<"shorten-64-to-32">; | def Shorten64To32 : DiagGroup<"shorten-64-to-32">; | ||
def : DiagGroup<"sign-promo">; | def : DiagGroup<"sign-promo">; | ||
def SignCompare : DiagGroup<"sign-compare">; | def SignCompare : DiagGroup<"sign-compare">; | ||
-def : DiagGroup<"switch-default">; | +def SwitchDefault : DiagGroup<"switch-default">; | ||
def : DiagGroup<"synth">; | def : DiagGroup<"synth">; | ||
def SizeofArrayArgum | def SizeofArrayArgum | ||
def SizeofArrayDecay | def SizeofArrayDecay | ||
@@ -1126,6 +1126,8 @@ def FutureAttrs : DiagGroup<"futur | |||
CXX17Attrs, | CXX17Attrs, | ||
CXX20Attrs]>; | CXX20Attrs]>; | ||
+def CXX23AttrsOnLamb | |||
+ | |||
// A warning group for warnings about using C++11 features as extensions in | // A warning group for warnings about using C++11 features as extensions in | ||
// earlier C++ versions. | // earlier C++ versions. | ||
def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNames | def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNames | ||
@@ -1145,7 +1147,7 @@ def CXX20 : DiagGroup<"c++20 | |||
// A warning group for warnings about using C++23 features as extensions in | // A warning group for warnings about using C++23 features as extensions in | ||
// earlier C++ versions. | // earlier C++ versions. | ||
-def CXX23 : DiagGroup<"c++23- | +def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>; | ||
// A warning group for warnings about using C++26 features as extensions in | // A warning group for warnings about using C++26 features as extensions in | ||
// earlier C++ versions. | // earlier C++ versions. |
@@ -1035,7 +1035,7 @@ def err_capture_defa | |||
"capture default must be first">; | "capture default must be first">; | ||
def ext_decl_attrs_o | def ext_decl_attrs_o | ||
"%select{an attribute specifier sequence|%0}1 in this position " | "%select{an attribute specifier sequence|%0}1 in this position " | ||
- "is a C++23 extension">, | + "is a C++23 extension">, InGroup<CXX23AttrsOnLambda>; | ||
def ext_lambda_missi | def ext_lambda_missi | ||
"lambda without a parameter clause is a C++23 extension">, | "lambda without a parameter clause is a C++23 extension">, | ||
InGroup<CXX23>; | InGroup<CXX23>; |
@@ -10064,6 +10064,8 @@ def warn_missing_cas | |||
"3:enumeration values %1, %2, and %3 not handled in switch|" | "3:enumeration values %1, %2, and %3 not handled in switch|" | ||
":%0 enumeration values not handled in switch: %1, %2, %3...}0">, | ":%0 enumeration values not handled in switch: %1, %2, %3...}0">, | ||
InGroup<Switch>; | InGroup<Switch>; | ||
+def warn_switch_defa | |||
+ InGroup<SwitchDefault>, DefaultIgnore; | |||
def warn_unannotated | def warn_unannotated | ||
"unannotated fall-through between switch labels">, | "unannotated fall-through between switch labels">, |
@@ -89,6 +89,8 @@ FEATURE(blocks, LangOpts.Blocks) | |||
FEATURE(c_thread_safety_ | FEATURE(c_thread_safety_ | ||
FEATURE(cxx_exceptions, LangOpts.CXXExceptions) | FEATURE(cxx_exceptions, LangOpts.CXXExceptions) | ||
FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData) | FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData) | ||
+EXTENSION(define_target_os | |||
+ PP.getPreprocessorO | |||
FEATURE(enumerator_attri | FEATURE(enumerator_attri | ||
FEATURE(nullability, true) | FEATURE(nullability, true) | ||
FEATURE(nullability_on_a | FEATURE(nullability_on_a |
@@ -53,7 +53,7 @@ enum class OpenACCDirective | |||
Shutdown, | Shutdown, | ||
Set, | Set, | ||
Update, | Update, | ||
- // FIXME: wait construct. | + Wait, | ||
// Procedure Calls in Compute Regions. | // Procedure Calls in Compute Regions. | ||
Routine, | Routine, |
@@ -40,6 +40,11 @@ namespace clang { | |||
/// Update getAsString. | /// Update getAsString. | ||
/// | /// | ||
enum class SyncScope { | enum class SyncScope { | ||
+ SystemScope, | |||
+ DeviceScope, | |||
+ WorkgroupScope, | |||
+ WavefrontScope, | |||
+ SingleScope, | |||
HIPSingleThread, | HIPSingleThread, | ||
HIPWavefront, | HIPWavefront, | ||
HIPWorkgroup, | HIPWorkgroup, | ||
@@ -54,6 +59,16 @@ enum class SyncScope { | |||
inline llvm::StringRef getAsString(SyncScope S) { | inline llvm::StringRef getAsString(SyncScope S) { | ||
switch (S) { | switch (S) { | ||
+ case SyncScope::SystemScope: | |||
+ return "system_scope"; | |||
+ case SyncScope::DeviceScope: | |||
+ return "device_scope"; | |||
+ case SyncScope::WorkgroupScope: | |||
+ return "workgroup_scope"; | |||
+ case SyncScope::WavefrontScope: | |||
+ return "wavefront_scope"; | |||
+ case SyncScope::SingleScope: | |||
+ return "single_scope"; | |||
case SyncScope::HIPSingleThread: | case SyncScope::HIPSingleThread: | ||
return "hip_singlethread | return "hip_singlethread | ||
case SyncScope::HIPWavefront: | case SyncScope::HIPWavefront: | ||
@@ -77,7 +92,7 @@ inline llvm::StringRef getAsString(Sync | |||
} | } | ||
/// Defines the kind of atomic scope models. | /// Defines the kind of atomic scope models. | ||
-enum class AtomicScopeModelKind { None, OpenCL, HIP }; | +enum class AtomicScopeModelKind { None, OpenCL, HIP, Generic }; | ||
/// Defines the interface for synch scope model. | /// Defines the interface for synch scope model. | ||
class AtomicScopeModel | class AtomicScopeModel | ||
@@ -205,6 +220,56 @@ public: | |||
} | } | ||
}; | }; | ||
+/// Defines the generic atomic scope model. | |||
+class AtomicScopeGener | |||
+public: | |||
+ /// The enum values match predefined built-in macros __ATOMIC_SCOPE_*. | |||
+ enum ID { | |||
+ System = 0, | |||
+ Device = 1, | |||
+ Workgroup = 2, | |||
+ Wavefront = 3, | |||
+ Single = 4, | |||
+ Last = Single | |||
+ }; | |||
+ | |||
+ AtomicScopeGener | |||
+ | |||
+ SyncScope map(unsigned S) const override { | |||
+ switch (static_cast<ID>(S)) { | |||
+ case Device: | |||
+ return SyncScope::DeviceScope; | |||
+ case System: | |||
+ return SyncScope::SystemScope; | |||
+ case Workgroup: | |||
+ return SyncScope::WorkgroupScope; | |||
+ case Wavefront: | |||
+ return SyncScope::WavefrontScope; | |||
+ case Single: | |||
+ return SyncScope::SingleScope; | |||
+ } | |||
+ llvm_unreachable | |||
+ } | |||
+ | |||
+ bool isValid(unsigned S) const override { | |||
+ return S >= static_cast<unsigned>(System) && | |||
+ S <= static_cast<unsigned>(Last); | |||
+ } | |||
+ | |||
+ ArrayRef<unsigned> getRuntimeValues | |||
+ static_assert(Last == Single, "Does not include all sync scopes"); | |||
+ static const unsigned Scopes[] = { | |||
+ static_cast<unsigned>(Device), static_cast<unsigned>(System), | |||
+ static_cast<unsigned>(Workgroup), static_cast<unsigned>(Wavefront), | |||
+ static_cast<unsigned>(Single)}; | |||
+ return llvm::ArrayRef(Scopes); | |||
+ } | |||
+ | |||
+ unsigned getFallBackValue | |||
+ return static_cast<unsigned>(System); | |||
+ } | |||
+}; | |||
+ | |||
inline std::unique_ptr<AtomicScopeModel | inline std::unique_ptr<AtomicScopeModel | ||
AtomicScopeModel | AtomicScopeModel | ||
switch (K) { | switch (K) { | ||
@@ -214,6 +279,8 @@ AtomicScopeModel | |||
return std::make_unique<AtomicScopeOpenC | return std::make_unique<AtomicScopeOpenC | ||
case AtomicScopeModel | case AtomicScopeModel | ||
return std::make_unique<AtomicScopeHIPMo | return std::make_unique<AtomicScopeHIPMo | ||
+ case AtomicScopeModel | |||
+ return std::make_unique<AtomicScopeGener | |||
} | } | ||
llvm_unreachable | llvm_unreachable | ||
} | } |
@@ -0,0 +1,55 @@ | |||
+//===--- TargetOSMacros.def - Target OS macros ------------------*- C++ -*-===// | |||
+// | |||
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
+// See https://llvm.org/LICENSE.txt for license information. | |||
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
+// | |||
+//===----------------------------------------------------------------------===// | |||
+// | |||
+// This file specifies the predefined TARGET_OS_* conditional macros. | |||
+// A target macro `Name` should be defined if `Predicate` evaluates to true. | |||
+// The macro expects `const llvm::Triple &Triple` and the class `llvm::Triple` | |||
+// to be available for the predicate. | |||
+// | |||
+//===----------------------------------------------------------------------===// | |||
+ | |||
+#ifndef TARGET_OS | |||
+#define TARGET_OS(Name, Predicate) | |||
+#endif | |||
+ | |||
+// Windows targets. | |||
+TARGET_OS(TARGET_OS_WIN32, | |||
+TARGET_OS(TARGET_OS_WINDOW | |||
+ | |||
+// Linux target. | |||
+TARGET_OS(TARGET_OS_LINUX, | |||
+ | |||
+// Unix target. | |||
+TARGET_OS(TARGET_OS_UNIX, Triple.isOSNetBSD() || | |||
+ Triple.isOSFreeBSD() || | |||
+ Triple.isOSOpenBSD() || | |||
+ Triple.isOSSolaris()) | |||
+ | |||
+// Apple (Mac) targets. | |||
+TARGET_OS(TARGET_OS_MAC, Triple.isOSDarwin()) | |||
+TARGET_OS(TARGET_OS_OSX, Triple.isMacOSX()) | |||
+TARGET_OS(TARGET_OS_IPHONE | |||
+ Triple.isWatchOS()) | |||
+// Triple::isiOS() also includes tvOS | |||
+TARGET_OS(TARGET_OS_IOS, Triple.getOS() == llvm::Triple::IOS) | |||
+TARGET_OS(TARGET_OS_TV, Triple.isTvOS()) | |||
+TARGET_OS(TARGET_OS_WATCH, | |||
+TARGET_OS(TARGET_OS_DRIVER | |||
+TARGET_OS(TARGET_OS_MACCAT | |||
+TARGET_OS(TARGET_OS_SIMULA | |||
+ | |||
+// Deprecated Apple target conditionals. | |||
+TARGET_OS(TARGET_OS_EMBEDD | |||
+ || Triple.isWatchOS()) \ | |||
+ && !Triple.isMacCatalystEnv | |||
+ && !Triple.isSimulatorEnvir | |||
+TARGET_OS(TARGET_OS_NANO, Triple.isWatchOS()) | |||
+TARGET_OS(TARGET_IPHONE_SI | |||
+TARGET_OS(TARGET_OS_UIKITF | |||
+ | |||
+#undef TARGET_OS |
@@ -1296,6 +1296,11 @@ def SVCREATE_3_BF16 : SInst<"svcreate3 | |||
def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate]>; | def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate]>; | ||
} | } | ||
+let TargetGuard = "sve2p1" in { | |||
+ def SVCREATE_2_B : SInst<"svcreate2[_{d}]", "2dd", "Pc", MergeNone, "", [IsTupleCreate]>; | |||
+ def SVCREATE_4_B : SInst<"svcreate4[_{d}]", "4dddd", "Pc", MergeNone, "", [IsTupleCreate]>; | |||
+} | |||
+ | |||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
// Vector insertion and extraction | // Vector insertion and extraction | ||
def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>; | def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>; | ||
@@ -1316,6 +1321,13 @@ def SVSET_3_BF16 : SInst<"svset3[_{ | |||
def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>; | def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>; | ||
} | } | ||
+let TargetGuard = "sve2p1" in { | |||
+ def SVGET_2_B : SInst<"svget2[_{d}]", "d2i", "Pc", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>; | |||
+ def SVGET_4_B : SInst<"svget4[_{d}]", "d4i", "Pc", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>; | |||
+ | |||
+ def SVSET_2_B : SInst<"svset2[_{d}]", "22id", "Pc", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>; | |||
+ def SVSET_4_B : SInst<"svset4[_{d}]", "44id", "Pc", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>; | |||
+} | |||
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||
// SVE2 WhileGE/GT | // SVE2 WhileGE/GT | ||
let TargetGuard = "sve2" in { | let TargetGuard = "sve2" in { | ||
@@ -2134,6 +2146,24 @@ let TargetGuard = "sme2" in { | |||
def SVURSHL_X2 : SInst<"svrshl[_{d}_x2]", "222", "UcUsUiUl", MergeNone, "aarch64_sve_ursh | def SVURSHL_X2 : SInst<"svrshl[_{d}_x2]", "222", "UcUsUiUl", MergeNone, "aarch64_sve_ursh | ||
def SVSRSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_srsh | def SVSRSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_srsh | ||
def SVURSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "UcUsUiUl", MergeNone, "aarch64_sve_ursh | def SVURSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "UcUsUiUl", MergeNone, "aarch64_sve_ursh | ||
+ | |||
+ def SVQRSHRN_X4 : SInst<"svqrshrn[_n]_{0}[_{d}_x4]", "q4i", "il", MergeNone, "aarch64_sve_sqrs | |||
+ def SVUQRSHRN_X4 : SInst<"svqrshrn[_n]_{0}[_{d}_x4]", "b4i", "UiUl", MergeNone, "aarch64_sve_uqrs | |||
+ | |||
+ // SQRSHR / UQRSHR | |||
+ def SVQRSHR_X2 : SInst<"svqrshr[_n]_{0}[_{d}_x2]", "h2i", "i", MergeNone, "aarch64_sve_sqrs | |||
+ def SVUQRSHR_X2 : SInst<"svqrshr[_n]_{0}[_{d}_x2]", "e2i", "Ui", MergeNone, "aarch64_sve_uqrs | |||
+ def SVQRSHR_X4 : SInst<"svqrshr[_n]_{0}[_{d}_x4]", "q4i", "il", MergeNone, "aarch64_sve_sqrs | |||
+ def SVUQRSHR_X4 : SInst<"svqrshr[_n]_{0}[_{d}_x4]", "b4i", "UiUl", MergeNone, "aarch64_sve_uqrs | |||
+ | |||
+ // SQRSHRU | |||
+ def SVSQRSHRU_X2 : SInst<"svqrshru[_n]_{0}[_{d}_x2]", "e2i", "i", MergeNone, "aarch64_sve_sqrs | |||
+ def SVSQRSHRU_X4 : SInst<"svqrshru[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrs | |||
+ | |||
+ def SVSQRSHRUN_X4 : SInst<"svqrshrun[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrs | |||
+ | |||
+ def REINTERPRET_SVBO | |||
+ def REINTERPRET_SVCO | |||
} | } | ||
let TargetGuard = "sve2p1" in { | let TargetGuard = "sve2p1" in { |
@@ -130,7 +130,7 @@ public: | |||
/// Select compatible variants, \returns false if none are compatible | /// Select compatible variants, \returns false if none are compatible | ||
bool select(const Multilib::flags_list &Flags, | bool select(const Multilib::flags_list &Flags, | ||
- | + llvm::SmallVectorImpl<Multilib> &) const; | ||
unsigned size() const { return Multilibs.size(); } | unsigned size() const { return Multilibs.size(); } | ||
@@ -1818,6 +1818,9 @@ def fcomment_block_c | |||
Visibility<[ClangOption, CC1Option]>, | Visibility<[ClangOption, CC1Option]>, | ||
HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, | HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, | ||
MetaVarName<"<arg>">, MarshallingInfoS | MetaVarName<"<arg>">, MarshallingInfoS | ||
+defm define_target_os | |||
+ "Enable", "Disable", " predefined target OS macros", | |||
+ [ClangOption, CC1Option]>; | |||
def fparse_all_comme | def fparse_all_comme | ||
Visibility<[ClangOption, CC1Option]>, | Visibility<[ClangOption, CC1Option]>, | ||
MarshallingInfoF | MarshallingInfoF |
@@ -151,6 +151,9 @@ class GenerateModuleIn | |||
private: | private: | ||
bool BeginSourceFileA | bool BeginSourceFileA | ||
+ std::unique_ptr<ASTConsumer> CreateASTConsume | |||
+ StringRef InFile) override; | |||
+ | |||
std::unique_ptr<raw_pwrite_strea | std::unique_ptr<raw_pwrite_strea | ||
CreateOutputFile | CreateOutputFile | ||
}; | }; |
@@ -247,16 +247,13 @@ class HeaderSearch { | |||
/// \#include search path information. Requests for \#include "x" search the | /// \#include search path information. Requests for \#include "x" search the | ||
/// directory of the \#including file first, then each directory in SearchDirs | /// directory of the \#including file first, then each directory in SearchDirs | ||
/// consecutively. Requests for <x> search the current dir first, then each | /// consecutively. Requests for <x> search the current dir first, then each | ||
- /// directory in SearchDirs, starting at AngledDirIdx, consecutively. | + /// directory in SearchDirs, starting at AngledDirIdx, consecutively. | ||
- /// NoCurDirSearch is true, then the check for the file in the current | |||
- /// directory is suppressed. | |||
std::vector<DirectoryLookup> SearchDirs; | std::vector<DirectoryLookup> SearchDirs; | ||
/// Whether the DirectoryLookup at the corresponding index in SearchDirs has | /// Whether the DirectoryLookup at the corresponding index in SearchDirs has | ||
/// been successfully used to lookup a file. | /// been successfully used to lookup a file. | ||
std::vector<bool> SearchDirsUsage; | std::vector<bool> SearchDirsUsage; | ||
unsigned AngledDirIdx = 0; | unsigned AngledDirIdx = 0; | ||
unsigned SystemDirIdx = 0; | unsigned SystemDirIdx = 0; | ||
- bool NoCurDirSearch = false; | |||
/// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used | /// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used | ||
/// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index | /// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index | ||
@@ -373,7 +370,7 @@ public: | |||
/// Interface for setting the file search paths. | /// Interface for setting the file search paths. | ||
void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx, | void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx, | ||
- unsigned systemDirIdx, | + unsigned systemDirIdx, | ||
llvm::DenseMap<unsigned, unsigned> searchDirToHSEnt | llvm::DenseMap<unsigned, unsigned> searchDirToHSEnt | ||
/// Add an additional search path. | /// Add an additional search path. |
@@ -76,6 +76,9 @@ public: | |||
/// predefines. | /// predefines. | ||
bool UsePredefines = true; | bool UsePredefines = true; | ||
+ /// Indicates whether to predefine target OS macros. | |||
+ bool DefineTargetOSMa | |||
+ | |||
/// Whether we should maintain a detailed record of all macro | /// Whether we should maintain a detailed record of all macro | ||
/// definitions and expansions. | /// definitions and expansions. | ||
bool DetailedRecord = false; | bool DetailedRecord = false; |
@@ -3544,6 +3544,7 @@ private: | |||
void ParseOpenACCCach | void ParseOpenACCCach | ||
/// Parses a single variable in a variable list for the 'cache' construct. | /// Parses a single variable in a variable list for the 'cache' construct. | ||
bool ParseOpenACCCach | bool ParseOpenACCCach | ||
+ bool ParseOpenACCWait | |||
private: | private: | ||
//===--------------------------------------------------------------------===// | //===--------------------------------------------------------------------===// |
@@ -30,9 +30,9 @@ class HLSLExternalSema | |||
void defineHLSLVector | void defineHLSLVector | ||
void defineTrivialHLS | void defineTrivialHLS | ||
- void | + void defineHLSLTypesWithForwardDeclarations(); | ||
- void completeBufferTy | + void onCompletion(CXXRecordDecl *Record, CompletionFuncti | ||
public: | public: | ||
~HLSLExternalSema | ~HLSLExternalSema |
@@ -4887,6 +4887,7 @@ unsigned AtomicExpr::getN | |||
case AO__atomic_load_ | case AO__atomic_load_ | ||
return 2; | return 2; | ||
+ case AO__scoped_atomi | |||
case AO__opencl_atomi | case AO__opencl_atomi | ||
case AO__hip_atomic_l | case AO__hip_atomic_l | ||
case AO__c11_atomic_s | case AO__c11_atomic_s | ||
@@ -4921,6 +4922,26 @@ unsigned AtomicExpr::getN | |||
case AO__atomic_fetch | case AO__atomic_fetch | ||
return 3; | return 3; | ||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
case AO__hip_atomic_e | case AO__hip_atomic_e | ||
case AO__hip_atomic_f | case AO__hip_atomic_f | ||
case AO__hip_atomic_f | case AO__hip_atomic_f | ||
@@ -4942,6 +4963,7 @@ unsigned AtomicExpr::getN | |||
case AO__atomic_excha | case AO__atomic_excha | ||
return 4; | return 4; | ||
+ case AO__scoped_atomi | |||
case AO__c11_atomic_c | case AO__c11_atomic_c | ||
case AO__c11_atomic_c | case AO__c11_atomic_c | ||
return 5; | return 5; | ||
@@ -4952,6 +4974,10 @@ unsigned AtomicExpr::getN | |||
case AO__atomic_compa | case AO__atomic_compa | ||
case AO__atomic_compa | case AO__atomic_compa | ||
return 6; | return 6; | ||
+ | |||
+ case AO__scoped_atomi | |||
+ case AO__scoped_atomi | |||
+ return 7; | |||
} | } | ||
llvm_unreachable | llvm_unreachable | ||
} | } |
@@ -15,7 +15,6 @@ | |||
#include "Function.h" | #include "Function.h" | ||
#include "PrimType.h" | #include "PrimType.h" | ||
#include "Program.h" | #include "Program.h" | ||
-#include "State.h" | |||
using namespace clang; | using namespace clang; | ||
using namespace clang::interp; | using namespace clang::interp; |
@@ -34,6 +34,19 @@ PrimType getIntPrimType(c | |||
llvm_unreachable | llvm_unreachable | ||
} | } | ||
+PrimType getLongPrimType(const InterpState &S) { | |||
+ const TargetInfo &TI = S.getCtx().getTargetInfo(); | |||
+ unsigned LongWidth = TI.getLongWidth(); | |||
+ | |||
+ if (LongWidth == 64) | |||
+ return PT_Sint64; | |||
+ else if (LongWidth == 32) | |||
+ return PT_Sint32; | |||
+ else if (LongWidth == 16) | |||
+ return PT_Sint16; | |||
+ llvm_unreachable | |||
+} | |||
+ | |||
/// Peek an integer value from the stack into an APSInt. | /// Peek an integer value from the stack into an APSInt. | ||
static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { | static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { | ||
if (Offset == 0) | if (Offset == 0) | ||
@@ -110,6 +123,19 @@ static void pushAPSInt(Inter | |||
} | } | ||
} | } | ||
+/// Pushes \p Val to the stack, as a target-dependent 'long'. | |||
+static void pushLong(InterpState &S, int64_t Val) { | |||
+ PrimType LongType = getLongPrimType(S); | |||
+ if (LongType == PT_Sint64) | |||
+ S.Stk.push<Integral<64, true>>(Integral<64, true>::from(Val)); | |||
+ else if (LongType == PT_Sint32) | |||
+ S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val)); | |||
+ else if (LongType == PT_Sint16) | |||
+ S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val)); | |||
+ else | |||
+ llvm_unreachable | |||
+} | |||
+ | |||
static void pushSizeT(InterpState &S, uint64_t Val) { | static void pushSizeT(InterpState &S, uint64_t Val) { | ||
const TargetInfo &TI = S.getCtx().getTargetInfo(); | const TargetInfo &TI = S.getCtx().getTargetInfo(); | ||
unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType()); | unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType()); | ||
@@ -533,6 +559,26 @@ static bool interp__builtin_ | |||
return true; | return true; | ||
} | } | ||
+// __builtin_expect | |||
+// __builtin_expect | |||
+static bool interp__builtin_ | |||
+ const InterpFrame *Frame, | |||
+ const Function *Func, const CallExpr *Call) { | |||
+ // The return value is simply the value of the first parameter. | |||
+ // We ignore the probability. | |||
+ unsigned NumArgs = Call->getNumArgs(); | |||
+ assert(NumArgs == 2 || NumArgs == 3); | |||
+ | |||
+ PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); | |||
+ unsigned Offset = align(primSize(getLongPrimType(S))) * 2; | |||
+ if (NumArgs == 3) | |||
+ Offset += align(primSize(PT_Float)); | |||
+ | |||
+ APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset); | |||
+ pushLong(S, Val.getSExtValue()); | |||
+ return true; | |||
+} | |||
+ | |||
bool InterpretBuiltin | bool InterpretBuiltin | ||
const CallExpr *Call) { | const CallExpr *Call) { | ||
InterpFrame *Frame = S.Current; | InterpFrame *Frame = S.Current; | ||
@@ -702,6 +748,12 @@ bool InterpretBuiltin | |||
return false; | return false; | ||
break; | break; | ||
+ case Builtin::BI__builtin_expe | |||
+ case Builtin::BI__builtin_expe | |||
+ if (!interp__builtin_ | |||
+ return false; | |||
+ break; | |||
+ | |||
default: | default: | ||
return false; | return false; | ||
} | } |
@@ -1841,6 +1841,7 @@ void StmtPrinter::Vis | |||
PrintExpr(Node->getPtr()); | PrintExpr(Node->getPtr()); | ||
if (Node->getOp() != AtomicExpr::AO__c11_atomic_l | if (Node->getOp() != AtomicExpr::AO__c11_atomic_l | ||
Node->getOp() != AtomicExpr::AO__atomic_load_ | Node->getOp() != AtomicExpr::AO__atomic_load_ | ||
+ Node->getOp() != AtomicExpr::AO__scoped_atomi | |||
Node->getOp() != AtomicExpr::AO__opencl_atomi | Node->getOp() != AtomicExpr::AO__opencl_atomi | ||
Node->getOp() != AtomicExpr::AO__hip_atomic_l | Node->getOp() != AtomicExpr::AO__hip_atomic_l | ||
OS << ", "; | OS << ", "; |
@@ -351,9 +351,10 @@ private: | |||
if (Invalid) | if (Invalid) | ||
return; | return; | ||
- static constexpr unsigned Missing = -1; | |||
// TokenInfo stores the BB and set of elements that a token is part of. | // TokenInfo stores the BB and set of elements that a token is part of. | ||
struct TokenInfo { | struct TokenInfo { | ||
+ enum : unsigned { Missing = static_cast<unsigned>(-1) }; | |||
+ | |||
// The basic block this is part of. | // The basic block this is part of. | ||
// This is the BB of the stmt with the smallest containing range. | // This is the BB of the stmt with the smallest containing range. | ||
unsigned BB = Missing; | unsigned BB = Missing; |
@@ -1010,6 +1010,8 @@ class ThreadSafetyAnal | |||
ThreadSafetyHand | ThreadSafetyHand | ||
const FunctionDecl *CurrentFunction; | const FunctionDecl *CurrentFunction; | ||
LocalVariableMap | LocalVariableMap | ||
+ // Maps constructed objects to `this` placeholder prior to initialization. | |||
+ llvm::SmallDenseMap<const Expr *, til::LiteralPtr *> ConstructedObjec | |||
FactManager FactMan; | FactManager FactMan; | ||
std::vector<CFGBlockInfo> BlockInfo; | std::vector<CFGBlockInfo> BlockInfo; | ||
@@ -1543,8 +1545,6 @@ class BuildLockset : public ConstStmtVisitor | |||
FactSet FSet; | FactSet FSet; | ||
// The fact set for the function on exit. | // The fact set for the function on exit. | ||
const FactSet &FunctionExitFSet | const FactSet &FunctionExitFSet | ||
- /// Maps constructed objects to `this` placeholder prior to initialization. | |||
- llvm::SmallDenseMap<const Expr *, til::LiteralPtr *> ConstructedObjec | |||
LocalVariableMap | LocalVariableMap | ||
unsigned CtxIndex; | unsigned CtxIndex; | ||
@@ -1808,7 +1808,7 @@ void BuildLockset::ha | |||
std::pair<til::LiteralPtr *, StringRef> Placeholder = | std::pair<til::LiteralPtr *, StringRef> Placeholder = | ||
Analyzer->SxBuilder.createThisPlaceh | Analyzer->SxBuilder.createThisPlaceh | ||
[[maybe_unused]] auto inserted = | [[maybe_unused]] auto inserted = | ||
- | + Analyzer->ConstructedObjects.insert({Exp, Placeholder.first}); | ||
assert(inserted.second && "Are we visiting the same expression again?"); | assert(inserted.second && "Are we visiting the same expression again?"); | ||
if (isa<CXXConstructExpr | if (isa<CXXConstructExpr | ||
Self = Placeholder.first; | Self = Placeholder.first; | ||
@@ -2128,10 +2128,10 @@ void BuildLockset::Vi | |||
E = EWC->getSubExpr()->IgnoreParens(); | E = EWC->getSubExpr()->IgnoreParens(); | ||
E = UnpackConstructi | E = UnpackConstructi | ||
- if (auto Object = | + if (auto Object = Analyzer->ConstructedObjects.find(E); | ||
- Object != | + Object != Analyzer->ConstructedObjects.end()) { | ||
Object->second->setClangDecl(VD); | Object->second->setClangDecl(VD); | ||
- | + Analyzer->ConstructedObjects.erase(Object); | ||
} | } | ||
} | } | ||
} | } | ||
@@ -2140,11 +2140,11 @@ void BuildLockset::Vi | |||
void BuildLockset::VisitMaterialize | void BuildLockset::VisitMaterialize | ||
const MaterializeTempo | const MaterializeTempo | ||
if (const ValueDecl *ExtD = Exp->getExtendingDecl | if (const ValueDecl *ExtD = Exp->getExtendingDecl | ||
- if (auto Object = | + if (auto Object = Analyzer->ConstructedObjects.find( | ||
- | + UnpackConstruction(Exp->getSubExpr())); | ||
- Object != | + Object != Analyzer->ConstructedObjects.end()) { | ||
Object->second->setClangDecl(ExtD); | Object->second->setClangDecl(ExtD); | ||
- | + Analyzer->ConstructedObjects.erase(Object); | ||
} | } | ||
} | } | ||
} | } | ||
@@ -2487,15 +2487,15 @@ void ThreadSafetyAnal | |||
// Clean up constructed object even if there are no attributes to | // Clean up constructed object even if there are no attributes to | ||
// keep the number of objects in limbo as small as possible. | // keep the number of objects in limbo as small as possible. | ||
- if (auto Object = | + if (auto Object = ConstructedObjects.find( | ||
TD.getBindTemporary | TD.getBindTemporary | ||
- Object != | + Object != ConstructedObjects.end()) { | ||
const auto *DD = TD.getDestructorDec | const auto *DD = TD.getDestructorDec | ||
if (DD->hasAttrs()) | if (DD->hasAttrs()) | ||
// TODO: the location here isn't quite correct. | // TODO: the location here isn't quite correct. | ||
LocksetBuilder.handleCall(nullptr, DD, Object->second, | LocksetBuilder.handleCall(nullptr, DD, Object->second, | ||
TD.getBindTemporary | TD.getBindTemporary | ||
- | + ConstructedObjects.erase(Object); | ||
} | } | ||
break; | break; | ||
} | } |
@@ -507,9 +507,11 @@ static llvm::Value *EmitPostAtomicM | |||
default: | default: | ||
llvm_unreachable | llvm_unreachable | ||
case AtomicExpr::AO__atomic_max_f | case AtomicExpr::AO__atomic_max_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Pred = IsSigned ? llvm::CmpInst::ICMP_SGT : llvm::CmpInst::ICMP_UGT; | Pred = IsSigned ? llvm::CmpInst::ICMP_SGT : llvm::CmpInst::ICMP_UGT; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_min_f | case AtomicExpr::AO__atomic_min_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Pred = IsSigned ? llvm::CmpInst::ICMP_SLT : llvm::CmpInst::ICMP_ULT; | Pred = IsSigned ? llvm::CmpInst::ICMP_SLT : llvm::CmpInst::ICMP_ULT; | ||
break; | break; | ||
} | } | ||
@@ -544,7 +546,9 @@ static void EmitAtomicOp(Cod | |||
FailureOrder, Size, Order, Scope); | FailureOrder, Size, Order, Scope); | ||
return; | return; | ||
case AtomicExpr::AO__atomic_compa | case AtomicExpr::AO__atomic_compa | ||
- case AtomicExpr::AO__atomic_compare_exchange_n: | + case AtomicExpr::AO__atomic_compare_exchange_n: | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) { | if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) { | ||
emitAtomicCmpXch | emitAtomicCmpXch | ||
Val1, Val2, FailureOrder, Size, Order, Scope); | Val1, Val2, FailureOrder, Size, Order, Scope); | ||
@@ -577,7 +581,9 @@ static void EmitAtomicOp(Cod | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__hip_atomic_l | case AtomicExpr::AO__hip_atomic_l | ||
case AtomicExpr::AO__atomic_load_ | case AtomicExpr::AO__atomic_load_ | ||
- case AtomicExpr::AO__atomic_load: | + case AtomicExpr::AO__atomic_load: | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); | llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); | ||
Load->setAtomic(Order, Scope); | Load->setAtomic(Order, Scope); | ||
Load->setVolatile(E->isVolatile()); | Load->setVolatile(E->isVolatile()); | ||
@@ -589,7 +595,9 @@ static void EmitAtomicOp(Cod | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__hip_atomic_s | case AtomicExpr::AO__hip_atomic_s | ||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
- case AtomicExpr::AO__atomic_store_n: | + case AtomicExpr::AO__atomic_store_n: | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); | llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); | ||
llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr); | llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr); | ||
Store->setAtomic(Order, Scope); | Store->setAtomic(Order, Scope); | ||
@@ -602,10 +610,13 @@ static void EmitAtomicOp(Cod | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_excha | case AtomicExpr::AO__atomic_excha | ||
case AtomicExpr::AO__atomic_excha | case AtomicExpr::AO__atomic_excha | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = llvm::AtomicRMWInst::Xchg; | Op = llvm::AtomicRMWInst::Xchg; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_add_f | case AtomicExpr::AO__atomic_add_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FAdd | PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FAdd | ||
: llvm::Instruction::Add; | : llvm::Instruction::Add; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
@@ -613,11 +624,13 @@ static void EmitAtomicOp(Cod | |||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd | Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd | ||
: llvm::AtomicRMWInst::Add; | : llvm::AtomicRMWInst::Add; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_sub_f | case AtomicExpr::AO__atomic_sub_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FSub | PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FSub | ||
: llvm::Instruction::Sub; | : llvm::Instruction::Sub; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
@@ -625,17 +638,20 @@ static void EmitAtomicOp(Cod | |||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub | Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub | ||
: llvm::AtomicRMWInst::Sub; | : llvm::AtomicRMWInst::Sub; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_min_f | case AtomicExpr::AO__atomic_min_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOpMinMax = true; | PostOpMinMax = true; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = E->getValueType()->isFloatingType() | Op = E->getValueType()->isFloatingType() | ||
? llvm::AtomicRMWInst::FMin | ? llvm::AtomicRMWInst::FMin | ||
: (E->getValueType()->isSignedIntegerT | : (E->getValueType()->isSignedIntegerT | ||
@@ -644,12 +660,14 @@ static void EmitAtomicOp(Cod | |||
break; | break; | ||
case AtomicExpr::AO__atomic_max_f | case AtomicExpr::AO__atomic_max_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOpMinMax = true; | PostOpMinMax = true; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = E->getValueType()->isFloatingType() | Op = E->getValueType()->isFloatingType() | ||
? llvm::AtomicRMWInst::FMax | ? llvm::AtomicRMWInst::FMax | ||
: (E->getValueType()->isSignedIntegerT | : (E->getValueType()->isSignedIntegerT | ||
@@ -658,40 +676,48 @@ static void EmitAtomicOp(Cod | |||
break; | break; | ||
case AtomicExpr::AO__atomic_and_f | case AtomicExpr::AO__atomic_and_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::And; | PostOp = llvm::Instruction::And; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = llvm::AtomicRMWInst::And; | Op = llvm::AtomicRMWInst::And; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_or_fe | case AtomicExpr::AO__atomic_or_fe | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::Or; | PostOp = llvm::Instruction::Or; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = llvm::AtomicRMWInst::Or; | Op = llvm::AtomicRMWInst::Or; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_xor_f | case AtomicExpr::AO__atomic_xor_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::Xor; | PostOp = llvm::Instruction::Xor; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = llvm::AtomicRMWInst::Xor; | Op = llvm::AtomicRMWInst::Xor; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_nand_ | case AtomicExpr::AO__atomic_nand_ | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::And; // the NOT is special cased below | PostOp = llvm::Instruction::And; // the NOT is special cased below | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Op = llvm::AtomicRMWInst::Nand; | Op = llvm::AtomicRMWInst::Nand; | ||
break; | break; | ||
} | } | ||
@@ -711,7 +737,8 @@ static void EmitAtomicOp(Cod | |||
else if (PostOp) | else if (PostOp) | ||
Result = CGF.Builder.CreateBinOp((llvm::Instruction::BinaryOps)PostOp, RMWI, | Result = CGF.Builder.CreateBinOp((llvm::Instruction::BinaryOps)PostOp, RMWI, | ||
LoadVal1); | LoadVal1); | ||
- if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch | + if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch || | ||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
Result = CGF.Builder.CreateNot(Result); | Result = CGF.Builder.CreateNot(Result); | ||
CGF.Builder.CreateStore(Result, Dest); | CGF.Builder.CreateStore(Result, Dest); | ||
} | } | ||
@@ -861,20 +888,24 @@ RValue CodeGenFunction: | |||
llvm_unreachable | llvm_unreachable | ||
case AtomicExpr::AO__atomic_load_ | case AtomicExpr::AO__atomic_load_ | ||
+ case AtomicExpr::AO__scoped_atomi | |||
case AtomicExpr::AO__c11_atomic_l | case AtomicExpr::AO__c11_atomic_l | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__hip_atomic_l | case AtomicExpr::AO__hip_atomic_l | ||
break; | break; | ||
case AtomicExpr::AO__atomic_load: | case AtomicExpr::AO__atomic_load: | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Dest = EmitPointerWithA | Dest = EmitPointerWithA | ||
break; | break; | ||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Val1 = EmitPointerWithA | Val1 = EmitPointerWithA | ||
break; | break; | ||
case AtomicExpr::AO__atomic_excha | case AtomicExpr::AO__atomic_excha | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Val1 = EmitPointerWithA | Val1 = EmitPointerWithA | ||
Dest = EmitPointerWithA | Dest = EmitPointerWithA | ||
break; | break; | ||
@@ -887,14 +918,19 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__hip_atomic_c | case AtomicExpr::AO__hip_atomic_c | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
Val1 = EmitPointerWithA | Val1 = EmitPointerWithA | ||
- if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange | + if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange || | ||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
Val2 = EmitPointerWithA | Val2 = EmitPointerWithA | ||
else | else | ||
Val2 = EmitValToTemp(*this, E->getVal2()); | Val2 = EmitValToTemp(*this, E->getVal2()); | ||
OrderFail = EmitScalarExpr(E->getOrderFail()); | OrderFail = EmitScalarExpr(E->getOrderFail()); | ||
if (E->getOp() == AtomicExpr::AO__atomic_compa | if (E->getOp() == AtomicExpr::AO__atomic_compa | ||
- E->getOp() == AtomicExpr::AO__atomic_compare_exchange | + E->getOp() == AtomicExpr::AO__atomic_compare_exchange || | ||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
IsWeak = EmitScalarExpr(E->getWeak()); | IsWeak = EmitScalarExpr(E->getWeak()); | ||
break; | break; | ||
@@ -934,6 +970,14 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
ShouldCastToIntP | ShouldCastToIntP | ||
[[fallthrough]]; | [[fallthrough]]; | ||
@@ -963,6 +1007,16 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
Val1 = EmitValToTemp(*this, E->getVal1()); | Val1 = EmitValToTemp(*this, E->getVal1()); | ||
break; | break; | ||
} | } | ||
@@ -1039,6 +1093,22 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
// For these, only library calls for certain sizes exist. | // For these, only library calls for certain sizes exist. | ||
UseOptimizedLibc | UseOptimizedLibc | ||
break; | break; | ||
@@ -1047,6 +1117,10 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
case AtomicExpr::AO__atomic_excha | case AtomicExpr::AO__atomic_excha | ||
case AtomicExpr::AO__atomic_compa | case AtomicExpr::AO__atomic_compa | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
// Use the generic version if we don't know that the operand will be | // Use the generic version if we don't know that the operand will be | ||
// suitably aligned for the optimized version. | // suitably aligned for the optimized version. | ||
if (Misaligned) | if (Misaligned) | ||
@@ -1071,6 +1145,10 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
// Only use optimized library calls for sizes for which they exist. | // Only use optimized library calls for sizes for which they exist. | ||
// FIXME: Size == 16 optimized library functions exist too. | // FIXME: Size == 16 optimized library functions exist too. | ||
if (Size == 1 || Size == 2 || Size == 4 || Size == 8) | if (Size == 1 || Size == 2 || Size == 4 || Size == 8) | ||
@@ -1131,6 +1209,8 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__hip_atomic_c | case AtomicExpr::AO__hip_atomic_c | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_compare | LibCallName = "__atomic_compare | ||
RetTy = getContext().BoolTy; | RetTy = getContext().BoolTy; | ||
HaveRetTy = true; | HaveRetTy = true; | ||
@@ -1150,6 +1230,8 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__c11_atomic_e | case AtomicExpr::AO__c11_atomic_e | ||
case AtomicExpr::AO__hip_atomic_e | case AtomicExpr::AO__hip_atomic_e | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_exchang | LibCallName = "__atomic_exchang | ||
AddDirectArgumen | AddDirectArgumen | ||
MemTy, E->getExprLoc(), TInfo.Width); | MemTy, E->getExprLoc(), TInfo.Width); | ||
@@ -1161,6 +1243,8 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__c11_atomic_s | case AtomicExpr::AO__c11_atomic_s | ||
case AtomicExpr::AO__hip_atomic_s | case AtomicExpr::AO__hip_atomic_s | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_store"; | LibCallName = "__atomic_store"; | ||
RetTy = getContext().VoidTy; | RetTy = getContext().VoidTy; | ||
HaveRetTy = true; | HaveRetTy = true; | ||
@@ -1174,17 +1258,21 @@ RValue CodeGenFunction: | |||
case AtomicExpr::AO__c11_atomic_l | case AtomicExpr::AO__c11_atomic_l | ||
case AtomicExpr::AO__hip_atomic_l | case AtomicExpr::AO__hip_atomic_l | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_load"; | LibCallName = "__atomic_load"; | ||
break; | break; | ||
// T __atomic_add_fet | // T __atomic_add_fet | ||
// T __atomic_fetch_a | // T __atomic_fetch_a | ||
case AtomicExpr::AO__atomic_add_f | case AtomicExpr::AO__atomic_add_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::Add; | PostOp = llvm::Instruction::Add; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_fetch_a | LibCallName = "__atomic_fetch_a | ||
AddDirectArgumen | AddDirectArgumen | ||
LoweredMemTy, E->getExprLoc(), TInfo.Width); | LoweredMemTy, E->getExprLoc(), TInfo.Width); | ||
@@ -1192,12 +1280,14 @@ RValue CodeGenFunction: | |||
// T __atomic_and_fet | // T __atomic_and_fet | ||
// T __atomic_fetch_a | // T __atomic_fetch_a | ||
case AtomicExpr::AO__atomic_and_f | case AtomicExpr::AO__atomic_and_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::And; | PostOp = llvm::Instruction::And; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_fetch_a | LibCallName = "__atomic_fetch_a | ||
AddDirectArgumen | AddDirectArgumen | ||
MemTy, E->getExprLoc(), TInfo.Width); | MemTy, E->getExprLoc(), TInfo.Width); | ||
@@ -1205,12 +1295,14 @@ RValue CodeGenFunction: | |||
// T __atomic_or_fetc | // T __atomic_or_fetc | ||
// T __atomic_fetch_o | // T __atomic_fetch_o | ||
case AtomicExpr::AO__atomic_or_fe | case AtomicExpr::AO__atomic_or_fe | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::Or; | PostOp = llvm::Instruction::Or; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_fetch_o | LibCallName = "__atomic_fetch_o | ||
AddDirectArgumen | AddDirectArgumen | ||
MemTy, E->getExprLoc(), TInfo.Width); | MemTy, E->getExprLoc(), TInfo.Width); | ||
@@ -1218,12 +1310,14 @@ RValue CodeGenFunction: | |||
// T __atomic_sub_fet | // T __atomic_sub_fet | ||
// T __atomic_fetch_s | // T __atomic_fetch_s | ||
case AtomicExpr::AO__atomic_sub_f | case AtomicExpr::AO__atomic_sub_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::Sub; | PostOp = llvm::Instruction::Sub; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_fetch_s | LibCallName = "__atomic_fetch_s | ||
AddDirectArgumen | AddDirectArgumen | ||
LoweredMemTy, E->getExprLoc(), TInfo.Width); | LoweredMemTy, E->getExprLoc(), TInfo.Width); | ||
@@ -1231,21 +1325,25 @@ RValue CodeGenFunction: | |||
// T __atomic_xor_fet | // T __atomic_xor_fet | ||
// T __atomic_fetch_x | // T __atomic_fetch_x | ||
case AtomicExpr::AO__atomic_xor_f | case AtomicExpr::AO__atomic_xor_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::Xor; | PostOp = llvm::Instruction::Xor; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_fetch_x | LibCallName = "__atomic_fetch_x | ||
AddDirectArgumen | AddDirectArgumen | ||
MemTy, E->getExprLoc(), TInfo.Width); | MemTy, E->getExprLoc(), TInfo.Width); | ||
break; | break; | ||
case AtomicExpr::AO__atomic_min_f | case AtomicExpr::AO__atomic_min_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOpMinMax = true; | PostOpMinMax = true; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
LibCallName = E->getValueType()->isSignedIntegerT | LibCallName = E->getValueType()->isSignedIntegerT | ||
@@ -1255,12 +1353,14 @@ RValue CodeGenFunction: | |||
LoweredMemTy, E->getExprLoc(), TInfo.Width); | LoweredMemTy, E->getExprLoc(), TInfo.Width); | ||
break; | break; | ||
case AtomicExpr::AO__atomic_max_f | case AtomicExpr::AO__atomic_max_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOpMinMax = true; | PostOpMinMax = true; | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__hip_atomic_f | case AtomicExpr::AO__hip_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = E->getValueType()->isSignedIntegerT | LibCallName = E->getValueType()->isSignedIntegerT | ||
? "__atomic_fetch_m | ? "__atomic_fetch_m | ||
: "__atomic_fetch_u | : "__atomic_fetch_u | ||
@@ -1270,10 +1370,12 @@ RValue CodeGenFunction: | |||
// T __atomic_nand_fe | // T __atomic_nand_fe | ||
// T __atomic_fetch_n | // T __atomic_fetch_n | ||
case AtomicExpr::AO__atomic_nand_ | case AtomicExpr::AO__atomic_nand_ | ||
+ case AtomicExpr::AO__scoped_atomi | |||
PostOp = llvm::Instruction::And; // the NOT is special cased below | PostOp = llvm::Instruction::And; // the NOT is special cased below | ||
[[fallthrough]]; | [[fallthrough]]; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
LibCallName = "__atomic_fetch_n | LibCallName = "__atomic_fetch_n | ||
AddDirectArgumen | AddDirectArgumen | ||
MemTy, E->getExprLoc(), TInfo.Width); | MemTy, E->getExprLoc(), TInfo.Width); | ||
@@ -1330,7 +1432,8 @@ RValue CodeGenFunction: | |||
llvm::Value *LoadVal1 = Args[1].getRValue(*this).getScalarVal(); | llvm::Value *LoadVal1 = Args[1].getRValue(*this).getScalarVal(); | ||
ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1); | ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1); | ||
} | } | ||
- if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch | + if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch || | ||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
ResVal = Builder.CreateNot(ResVal); | ResVal = Builder.CreateNot(ResVal); | ||
Builder.CreateStore(ResVal, Dest.withElementType(ResVal->getType())); | Builder.CreateStore(ResVal, Dest.withElementType(ResVal->getType())); | ||
@@ -1347,12 +1450,16 @@ RValue CodeGenFunction: | |||
E->getOp() == AtomicExpr::AO__opencl_atomi | E->getOp() == AtomicExpr::AO__opencl_atomi | ||
E->getOp() == AtomicExpr::AO__hip_atomic_s | E->getOp() == AtomicExpr::AO__hip_atomic_s | ||
E->getOp() == AtomicExpr::AO__atomic_store | E->getOp() == AtomicExpr::AO__atomic_store | ||
- E->getOp() == | + E->getOp() == AtomicExpr::AO__atomic_store_n || | ||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_l | bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_l | ||
E->getOp() == AtomicExpr::AO__opencl_atomi | E->getOp() == AtomicExpr::AO__opencl_atomi | ||
E->getOp() == AtomicExpr::AO__hip_atomic_l | E->getOp() == AtomicExpr::AO__hip_atomic_l | ||
E->getOp() == AtomicExpr::AO__atomic_load || | E->getOp() == AtomicExpr::AO__atomic_load || | ||
- E->getOp() == | + E->getOp() == AtomicExpr::AO__atomic_load_n || | ||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
+ E->getOp() == AtomicExpr::AO__scoped_atomi | |||
if (isa<llvm::ConstantInt>(Order)) { | if (isa<llvm::ConstantInt>(Order)) { | ||
auto ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); | auto ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); |
@@ -10211,6 +10211,22 @@ Value *CodeGenFunction | |||
switch (BuiltinID) { | switch (BuiltinID) { | ||
default: | default: | ||
return nullptr; | return nullptr; | ||
+ | |||
+ case SVE::BI__builtin_sve_ | |||
+ auto SVCountTy = | |||
+ llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount"); | |||
+ Function *CastFromSVCountF | |||
+ CGM.getIntrinsic(Intrinsic::aarch64_sve_conv | |||
+ return Builder.CreateCall(CastFromSVCountF | |||
+ } | |||
+ case SVE::BI__builtin_sve_ | |||
+ auto SVCountTy = | |||
+ llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount"); | |||
+ Function *CastToSVCountF = | |||
+ CGM.getIntrinsic(Intrinsic::aarch64_sve_conv | |||
+ return Builder.CreateCall(CastToSVCountF, Ops[0]); | |||
+ } | |||
+ | |||
case SVE::BI__builtin_sve_ | case SVE::BI__builtin_sve_ | ||
case SVE::BI__builtin_sve_ | case SVE::BI__builtin_sve_ | ||
case SVE::BI__builtin_sve_ | case SVE::BI__builtin_sve_ |
@@ -1132,26 +1132,39 @@ void CGNVCUDARuntime: | |||
for (KernelInfo &I : EmittedKernels) | for (KernelInfo &I : EmittedKernels) | ||
llvm::offloading::emitOffloadingEn | llvm::offloading::emitOffloadingEn | ||
M, KernelHandles[I.Kernel->getName()], | M, KernelHandles[I.Kernel->getName()], | ||
- getDeviceSideName(cast<NamedDecl>(I.D)), 0, | + getDeviceSideName(cast<NamedDecl>(I.D)), /*Flags=*/0, /*Data=*/0, | ||
- | + llvm::offloading::OffloadGlobalEntry, Section); | ||
for (VarInfo &I : DeviceVars) { | for (VarInfo &I : DeviceVars) { | ||
uint64_t VarSize = | uint64_t VarSize = | ||
CGM.getDataLayout().getTypeAllocSize | CGM.getDataLayout().getTypeAllocSize | ||
+ int32_t Flags = | |||
+ (I.Flags.isExtern() | |||
+ ? static_cast<int32_t>(llvm::offloading::OffloadGlobalExt | |||
+ : 0) | | |||
+ (I.Flags.isConstant() | |||
+ ? static_cast<int32_t>(llvm::offloading::OffloadGlobalCon | |||
+ : 0) | | |||
+ (I.Flags.isNormalized() | |||
+ ? static_cast<int32_t>(llvm::offloading::OffloadGlobalNor | |||
+ : 0); | |||
if (I.Flags.getKind() == DeviceVarFlags::Variable) { | if (I.Flags.getKind() == DeviceVarFlags::Variable) { | ||
llvm::offloading::emitOffloadingEn | llvm::offloading::emitOffloadingEn | ||
M, I.Var, getDeviceSideNam | M, I.Var, getDeviceSideNam | ||
- I.Flags.isManaged() ? | + (I.Flags.isManaged() ? llvm::offloading::OffloadGlobalManagedEntry | ||
- | + : llvm::offloading::OffloadGlobalEntry) | | ||
- Section); | + Flags, | ||
+ /*Data=*/0, Section); | |||
} else if (I.Flags.getKind() == DeviceVarFlags::Surface) { | } else if (I.Flags.getKind() == DeviceVarFlags::Surface) { | ||
llvm::offloading::emitOffloadingEn | llvm::offloading::emitOffloadingEn | ||
M, I.Var, getDeviceSideNam | M, I.Var, getDeviceSideNam | ||
- | + llvm::offloading::OffloadGlobalSurfaceEntry | Flags, | ||
+ I.Flags.getSurfTexType(), Section); | |||
} else if (I.Flags.getKind() == DeviceVarFlags::Texture) { | } else if (I.Flags.getKind() == DeviceVarFlags::Texture) { | ||
llvm::offloading::emitOffloadingEn | llvm::offloading::emitOffloadingEn | ||
M, I.Var, getDeviceSideNam | M, I.Var, getDeviceSideNam | ||
- | + llvm::offloading::OffloadGlobalTextureEntry | Flags, | ||
+ I.Flags.getSurfTexType(), Section); | |||
} | } | ||
} | } | ||
} | } |
@@ -17,6 +17,7 @@ | |||
#include "clang/AST/GlobalDecl.h" | #include "clang/AST/GlobalDecl.h" | ||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | ||
+#include "llvm/Frontend/Offloading/Utility.h" | |||
#include "llvm/IR/GlobalValue.h" | #include "llvm/IR/GlobalValue.h" | ||
namespace llvm { | namespace llvm { | ||
@@ -52,19 +53,6 @@ public: | |||
Texture, // Builtin texture | Texture, // Builtin texture | ||
}; | }; | ||
- /// The kind flag for an offloading entry. | |||
- enum OffloadEntryKind | |||
- /// Mark the entry as a global entry. This indicates the presense of a | |||
- /// kernel if the size field is zero and a variable otherwise. | |||
- OffloadGlobalEnt | |||
- /// Mark the entry as a managed global variable. | |||
- OffloadGlobalMan | |||
- /// Mark the entry as a surface variable. | |||
- OffloadGlobalSur | |||
- /// Mark the entry as a texture variable. | |||
- OffloadGlobalTex | |||
- }; | |||
- | |||
private: | private: | ||
unsigned Kind : 2; | unsigned Kind : 2; | ||
unsigned Extern : 1; | unsigned Extern : 1; |
@@ -7389,7 +7389,14 @@ private: | |||
} else if (FieldIndex < PartialStruct.LowestElem.first) { | } else if (FieldIndex < PartialStruct.LowestElem.first) { | ||
PartialStruct.LowestElem = {FieldIndex, LowestElem}; | PartialStruct.LowestElem = {FieldIndex, LowestElem}; | ||
} else if (FieldIndex > PartialStruct.HighestElem.first) { | } else if (FieldIndex > PartialStruct.HighestElem.first) { | ||
- PartialStruct.HighestElem = {FieldIndex, LowestElem}; | + if (IsFinalArraySect | ||
+ Address HB = | |||
+ CGF.EmitOMPArraySect | |||
+ .getAddress(CGF); | |||
+ PartialStruct.HighestElem = {FieldIndex, HB}; | |||
+ } else { | |||
+ PartialStruct.HighestElem = {FieldIndex, LowestElem}; | |||
+ } | |||
} | } | ||
} | } | ||
@@ -6439,7 +6439,7 @@ ConstantAddress CodeGenModule::G | |||
VD, E->getManglingNumbe | VD, E->getManglingNumbe | ||
APValue *Value = nullptr; | APValue *Value = nullptr; | ||
- if (E->getStorageDuration() == SD_Static && VD | + if (E->getStorageDuration() == SD_Static && VD->evaluateValue()) { | ||
// If the initializer of the extending declaration is a constant | // If the initializer of the extending declaration is a constant | ||
// initializer, we should have a cached constant initializer for this | // initializer, we should have a cached constant initializer for this | ||
// temporary. Note that this might have a different value from the value | // temporary. Note that this might have a different value from the value | ||
@@ -6454,8 +6454,7 @@ ConstantAddress CodeGenModule::G | |||
!EvalResult.hasSideEffects()) | !EvalResult.hasSideEffects()) | ||
Value = &EvalResult.Val; | Value = &EvalResult.Val; | ||
- LangAS AddrSpace = | + LangAS AddrSpace = GetGlobalVarAddressSpace(VD); | ||
- VD ? GetGlobalVarAddr | |||
std::optional<ConstantEmitter> emitter; | std::optional<ConstantEmitter> emitter; | ||
llvm::Constant *InitialValue = nullptr; | llvm::Constant *InitialValue = nullptr; |
@@ -196,11 +196,14 @@ llvm::MDNode *CodeGenTBAA::ge | |||
// Enum types are distinct types. In C++ they have "underlying types", | // Enum types are distinct types. In C++ they have "underlying types", | ||
// however they aren't related for TBAA. | // however they aren't related for TBAA. | ||
if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { | if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { | ||
+ if (!Features.CPlusPlus) | |||
+ return getTypeInfo(ETy->getDecl()->getIntegerType()); | |||
+ | |||
// In C++ mode, types have linkage, so we can rely on the ODR and | // In C++ mode, types have linkage, so we can rely on the ODR and | ||
// on their mangled names, if they're external. | // on their mangled names, if they're external. | ||
// TODO: Is there a way to get a program-wide unique name for a | // TODO: Is there a way to get a program-wide unique name for a | ||
// decl with local linkage or no linkage? | // decl with local linkage or no linkage? | ||
- if ( | + if (!ETy->getDecl()->isExternallyVisible()) | ||
return getChar(); | return getChar(); | ||
SmallString<256> OutName; | SmallString<256> OutName; |
@@ -471,20 +471,25 @@ AMDGPUTargetCode | |||
std::string Name; | std::string Name; | ||
switch (Scope) { | switch (Scope) { | ||
case SyncScope::HIPSingleThread: | case SyncScope::HIPSingleThread: | ||
+ case SyncScope::SingleScope: | |||
Name = "singlethread"; | Name = "singlethread"; | ||
break; | break; | ||
case SyncScope::HIPWavefront: | case SyncScope::HIPWavefront: | ||
case SyncScope::OpenCLSubGroup: | case SyncScope::OpenCLSubGroup: | ||
+ case SyncScope::WavefrontScope: | |||
Name = "wavefront"; | Name = "wavefront"; | ||
break; | break; | ||
case SyncScope::HIPWorkgroup: | case SyncScope::HIPWorkgroup: | ||
case SyncScope::OpenCLWorkGroup: | case SyncScope::OpenCLWorkGroup: | ||
+ case SyncScope::WorkgroupScope: | |||
Name = "workgroup"; | Name = "workgroup"; | ||
break; | break; | ||
case SyncScope::HIPAgent: | case SyncScope::HIPAgent: | ||
case SyncScope::OpenCLDevice: | case SyncScope::OpenCLDevice: | ||
+ case SyncScope::DeviceScope: | |||
Name = "agent"; | Name = "agent"; | ||
break; | break; | ||
+ case SyncScope::SystemScope: | |||
case SyncScope::HIPSystem: | case SyncScope::HIPSystem: | ||
case SyncScope::OpenCLAllSVMDevi | case SyncScope::OpenCLAllSVMDevi | ||
Name = ""; | Name = ""; |
@@ -95,7 +95,7 @@ MultilibSet &MultilibSet::Fi | |||
void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } | void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } | ||
bool MultilibSet::select(const Multilib::flags_list &Flags, | bool MultilibSet::select(const Multilib::flags_list &Flags, | ||
- | + llvm::SmallVectorImpl<Multilib> &Selected) const { | ||
llvm::StringSet<> FlagSet(expandFlags(Flags)); | llvm::StringSet<> FlagSet(expandFlags(Flags)); | ||
Selected.clear(); | Selected.clear(); | ||
@@ -1294,6 +1294,9 @@ void Clang::AddPrepro | |||
CmdArgs.push_back("-source-date-epoch"); | CmdArgs.push_back("-source-date-epoch"); | ||
CmdArgs.push_back(Args.MakeArgString(Epoch)); | CmdArgs.push_back(Args.MakeArgString(Epoch)); | ||
} | } | ||
+ | |||
+ Args.addOptInFlag(CmdArgs, options::OPT_fdefine_targ | |||
+ options::OPT_fno_define_t | |||
} | } | ||
// FIXME: Move to target hook. | // FIXME: Move to target hook. |
@@ -2583,9 +2583,7 @@ void tools::addMachin | |||
// We only support -moutline in AArch64 and ARM targets right now. If | // We only support -moutline in AArch64 and ARM targets right now. If | ||
// we're not compiling for these, emit a warning and ignore the flag. | // we're not compiling for these, emit a warning and ignore the flag. | ||
// Otherwise, add the proper mllvm flags. | // Otherwise, add the proper mllvm flags. | ||
- if (!(Triple.isARM() || Triple.isThumb() || | + if (!(Triple.isARM() || Triple.isThumb() || Triple.isAArch64())) { | ||
- Triple.getArch() == llvm::Triple::aarch64 || | |||
- Triple.getArch() == llvm::Triple::aarch64_32)) { | |||
D.Diag(diag::warn_drv_moutlin | D.Diag(diag::warn_drv_moutlin | ||
} else { | } else { | ||
addArg(Twine("-enable-machine-outliner")); | addArg(Twine("-enable-machine-outliner")); |
@@ -199,9 +199,10 @@ StringRef getLanguageName( | |||
return "objective-c"; | return "objective-c"; | ||
case Language::CXX: | case Language::CXX: | ||
return "c++"; | return "c++"; | ||
+ case Language::ObjCXX: | |||
+ return "objective-c++"; | |||
// Unsupported language currently | // Unsupported language currently | ||
- case Language::ObjCXX: | |||
case Language::OpenCL: | case Language::OpenCL: | ||
case Language::OpenCLCXX: | case Language::OpenCLCXX: | ||
case Language::CUDA: | case Language::CUDA: |
@@ -1259,7 +1259,7 @@ unsigned ContinuationInde | |||
} | } | ||
if (Style.AlignAfterOpenBr | if (Style.AlignAfterOpenBr | ||
(Current.is(tok::r_paren) || | (Current.is(tok::r_paren) || | ||
- (Current.is(tok::r_brace) && | + (Current.is(tok::r_brace) && Current.MatchingParen && | ||
Current.MatchingParen->is(BK_BracedInit))) && | Current.MatchingParen->is(BK_BracedInit))) && | ||
State.Stack.size() > 1) { | State.Stack.size() > 1) { | ||
return State.Stack[State.Stack.size() - 2].LastSpace; | return State.Stack[State.Stack.size() - 2].LastSpace; |
@@ -411,9 +411,16 @@ private: | |||
} | } | ||
} | } | ||
+ const auto *LastNonComment = TheLine->getLastNonCommen | |||
+ assert(LastNonComment); | |||
+ // FIXME: There are probably cases where we should use LastNonComment | |||
+ // instead of TheLine->Last. | |||
+ | |||
// Try to merge a function block with left brace unwrapped. | // Try to merge a function block with left brace unwrapped. | ||
- if (TheLine->Last->is(TT_FunctionLBrac | + if (LastNonComment->is(TT_FunctionLBrac | ||
+ TheLine->First != LastNonComment) { | |||
return MergeShortFuncti | return MergeShortFuncti | ||
+ } | |||
// Try to merge a control statement block with left brace unwrapped. | // Try to merge a control statement block with left brace unwrapped. | ||
if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last && | if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last && | ||
FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, | FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, | ||
@@ -789,7 +796,8 @@ private: | |||
} | } | ||
} | } | ||
- if (Line.Last->is(tok::l_brace)) { | + if (const auto *LastNonComment = Line.getLastNonCommen | ||
+ LastNonComment && LastNonComment->is(tok::l_brace)) { | |||
if (IsSplitBlock && Line.First == Line.Last && | if (IsSplitBlock && Line.First == Line.Last && | ||
I > AnnotatedLines.begin() && | I > AnnotatedLines.begin() && | ||
(I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) { | (I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) { | ||
@@ -805,7 +813,8 @@ private: | |||
if (ShouldMerge()) { | if (ShouldMerge()) { | ||
// We merge empty blocks even if the line exceeds the column limit. | // We merge empty blocks even if the line exceeds the column limit. | ||
- Tok->SpacesRequiredBefore = | + Tok->SpacesRequiredBefore = | ||
+ (Style.SpaceInEmptyBloc | |||
Tok->CanBreakBefore = true; | Tok->CanBreakBefore = true; | ||
return 1; | return 1; | ||
} else if (Limit != 0 && !Line.startsWithNamesp | } else if (Limit != 0 && !Line.startsWithNamesp |
@@ -4365,6 +4365,9 @@ static void GeneratePreproce | |||
if (Opts.SourceDateEpoch) | if (Opts.SourceDateEpoch) | ||
GenerateArg(Consumer, OPT_source_date_ | GenerateArg(Consumer, OPT_source_date_ | ||
+ if (Opts.DefineTargetOSMa | |||
+ GenerateArg(Consumer, OPT_fdefine_targ | |||
+ | |||
// Don't handle LexEditorPlaceho | // Don't handle LexEditorPlaceho | ||
// generated elsewhere. | // generated elsewhere. | ||
} | } | ||
@@ -4463,6 +4466,10 @@ static bool ParsePreprocesso | |||
if (isStrictlyPrepro | if (isStrictlyPrepro | ||
Opts.LexEditorPlaceho | Opts.LexEditorPlaceho | ||
+ Opts.DefineTargetOSMa | |||
+ Args.hasFlag(OPT_fdefine_targ | |||
+ OPT_fno_define_t | |||
+ | |||
return Diags.getNumErrors() == NumErrorsBefore; | return Diags.getNumErrors() == NumErrorsBefore; | ||
} | } | ||
@@ -258,6 +258,16 @@ bool GenerateModuleIn | |||
return GenerateModuleAc | return GenerateModuleAc | ||
} | } | ||
+std::unique_ptr<ASTConsumer> | |||
+GenerateModuleIn | |||
+ StringRef InFile) { | |||
+ CI.getHeaderSearchO | |||
+ CI.getHeaderSearchO | |||
+ CI.getHeaderSearchO | |||
+ | |||
+ return GenerateModuleAc | |||
+} | |||
+ | |||
std::unique_ptr<raw_pwrite_strea | std::unique_ptr<raw_pwrite_strea | ||
GenerateModuleIn | GenerateModuleIn | ||
StringRef InFile) { | StringRef InFile) { |
@@ -809,6 +809,13 @@ static void InitializePredef | |||
Builder.defineMacro("__ATOMIC_ACQ_REL | Builder.defineMacro("__ATOMIC_ACQ_REL | ||
Builder.defineMacro("__ATOMIC_SEQ_CST | Builder.defineMacro("__ATOMIC_SEQ_CST | ||
+ // Define macros for the clang atomic scopes. | |||
+ Builder.defineMacro("__MEMORY_SCOPE_S | |||
+ Builder.defineMacro("__MEMORY_SCOPE_D | |||
+ Builder.defineMacro("__MEMORY_SCOPE_W | |||
+ Builder.defineMacro("__MEMORY_SCOPE_W | |||
+ Builder.defineMacro("__MEMORY_SCOPE_S | |||
+ | |||
// Define macros for the OpenCL memory scope. | // Define macros for the OpenCL memory scope. | ||
// The values should match AtomicScopeOpenC | // The values should match AtomicScopeOpenC | ||
static_assert( | static_assert( | ||
@@ -1344,6 +1351,15 @@ static void InitializePredef | |||
if (TI.getTriple().isOSBinFormatELF | if (TI.getTriple().isOSBinFormatELF | ||
Builder.defineMacro("__ELF__"); | Builder.defineMacro("__ELF__"); | ||
+ // Target OS macro definitions. | |||
+ if (PPOpts.DefineTargetOSMa | |||
+ const llvm::Triple &Triple = TI.getTriple(); | |||
+#define TARGET_OS(Name, Predicate) \ | |||
+ Builder.defineMacro(#Name, (Predicate) ? "1" : "0"); | |||
+#include "clang/Basic/TargetOSMacros.def" | |||
+#undef TARGET_OS | |||
+ } | |||
+ | |||
// Get other target #defines. | // Get other target #defines. | ||
TI.getTargetDefines | TI.getTargetDefines | ||
} | } |
@@ -105,7 +105,7 @@ void HeaderSearch::Pr | |||
void HeaderSearch::SetSearchPaths( | void HeaderSearch::SetSearchPaths( | ||
std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx, | std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx, | ||
- unsigned int systemDirIdx, | + unsigned int systemDirIdx, | ||
llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEnt | llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEnt | ||
assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && | assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && | ||
"Directory indices are unordered"); | "Directory indices are unordered"); | ||
@@ -113,7 +113,6 @@ void HeaderSearch::Se | |||
SearchDirsUsage.assign(SearchDirs.size(), false); | SearchDirsUsage.assign(SearchDirs.size(), false); | ||
AngledDirIdx = angledDirIdx; | AngledDirIdx = angledDirIdx; | ||
SystemDirIdx = systemDirIdx; | SystemDirIdx = systemDirIdx; | ||
- NoCurDirSearch = noCurDirSearch; | |||
SearchDirToHSEnt | SearchDirToHSEnt | ||
//LookupFileCache.clear(); | //LookupFileCache.clear(); | ||
indexInitialHead | indexInitialHead | ||
@@ -904,12 +903,12 @@ OptionalFileEntr | |||
ModuleMap::KnownHeader MSSuggestedModul | ModuleMap::KnownHeader MSSuggestedModul | ||
OptionalFileEntr | OptionalFileEntr | ||
- // | + // Check to see if the file is in the #includer's directory. This cannot be | ||
- // | + // based on CurDir, because each includer could be a #include of a | ||
- // | + // subdirectory (#include "foo/bar.h") and a subsequent include of "baz.h" | ||
- // include of "baz.h" should resolve to "whatever/foo/baz.h". | + // should resolve to "whatever/foo/baz.h". This search is not done for <> | ||
- // This search is not done for <> headers. | + // headers. | ||
- if (!Includers.empty() && !isAngled | + if (!Includers.empty() && !isAngled) { | ||
SmallString<1024> TmpDir; | SmallString<1024> TmpDir; | ||
bool First = true; | bool First = true; | ||
for (const auto &IncluderAndDir : Includers) { | for (const auto &IncluderAndDir : Includers) { |
@@ -513,9 +513,8 @@ void InitHeaderSearch | |||
unsigned NonSystemRemoved | unsigned NonSystemRemoved | ||
NumAngled -= NonSystemRemoved | NumAngled -= NonSystemRemoved | ||
- bool DontSearchCurDir | |||
Headers.SetSearchPaths(extractLookups(SearchList), NumQuoted, NumAngled, | Headers.SetSearchPaths(extractLookups(SearchList), NumQuoted, NumAngled, | ||
- | + mapToUserEntries(SearchList)); | ||
Headers.SetSystemHeaderP | Headers.SetSystemHeaderP | ||
@@ -56,6 +56,7 @@ OpenACCDirective | |||
.Case("shutdown", OpenACCDirective | .Case("shutdown", OpenACCDirective | ||
.Case("set", OpenACCDirective | .Case("set", OpenACCDirective | ||
.Case("update", OpenACCDirective | .Case("update", OpenACCDirective | ||
+ .Case("wait", OpenACCDirective | |||
.Default(OpenACCDirective | .Default(OpenACCDirective | ||
if (DirKind != OpenACCDirective | if (DirKind != OpenACCDirective | ||
@@ -82,6 +83,27 @@ OpenACCAtomicKin | |||
.Default(OpenACCAtomicKin | .Default(OpenACCAtomicKin | ||
} | } | ||
+enum class OpenACCSpecialTo | |||
+ ReadOnly, | |||
+ DevNum, | |||
+ Queues, | |||
+}; | |||
+ | |||
+bool isOpenACCSpecial | |||
+ if (!Tok.is(tok::identifier)) | |||
+ return false; | |||
+ | |||
+ switch (Kind) { | |||
+ case OpenACCSpecialTo | |||
+ return Tok.getIdentifierInf | |||
+ case OpenACCSpecialTo | |||
+ return Tok.getIdentifierInf | |||
+ case OpenACCSpecialTo | |||
+ return Tok.getIdentifierInf | |||
+ } | |||
+ llvm_unreachable | |||
+} | |||
+ | |||
bool isOpenACCDirecti | bool isOpenACCDirecti | ||
if (!Tok.is(tok::identifier)) | if (!Tok.is(tok::identifier)) | ||
return false; | return false; | ||
@@ -123,6 +145,8 @@ bool isOpenACCDirecti | |||
return Tok.getIdentifierInf | return Tok.getIdentifierInf | ||
case OpenACCDirective | case OpenACCDirective | ||
return Tok.getIdentifierInf | return Tok.getIdentifierInf | ||
+ case OpenACCDirective | |||
+ return Tok.getIdentifierInf | |||
case OpenACCDirective | case OpenACCDirective | ||
return false; | return false; | ||
} | } | ||
@@ -182,7 +206,7 @@ OpenACCDirective | |||
// Just #pragma acc can get us immediately to the end, make sure we don't | // Just #pragma acc can get us immediately to the end, make sure we don't | ||
// introspect on the spelling before then. | // introspect on the spelling before then. | ||
- if (FirstTok. | + if (FirstTok.isNot(tok::identifier)) { | ||
P.Diag(FirstTok, diag::err_acc_missing_ | P.Diag(FirstTok, diag::err_acc_missing_ | ||
return OpenACCDirective | return OpenACCDirective | ||
} | } | ||
@@ -200,11 +224,8 @@ OpenACCDirective | |||
if (ExDirKind >= OpenACCDirective | if (ExDirKind >= OpenACCDirective | ||
switch (ExDirKind) { | switch (ExDirKind) { | ||
case OpenACCDirective | case OpenACCDirective | ||
- | + P.Diag(FirstTok, diag::err_acc_invalid_directive) | ||
- P.Diag(FirstTok, diag::err_expected) << tok::identifier; | + << 0 << FirstTok.getIdentifierInf | ||
- else | |||
- P.Diag(FirstTok, diag::err_acc_invalid_ | |||
- << 0 << FirstTok.getIdentifierInf | |||
return OpenACCDirective | return OpenACCDirective | ||
} | } | ||
case OpenACCDirective | case OpenACCDirective | ||
@@ -251,6 +272,67 @@ void ParseOpenACCClau | |||
} // namespace | } // namespace | ||
+/// OpenACC 3.3, section 2.16: | |||
+/// In this section and throughout the specification, the term wait-argument | |||
+/// means: | |||
+/// [ devnum : int-expr : ] [ queues : ] async-argument-list | |||
+bool Parser::ParseOpenACCWait | |||
+ // [devnum : int-expr : ] | |||
+ if (isOpenACCSpecial | |||
+ NextToken().is(tok::colon)) { | |||
+ // Consume devnum. | |||
+ ConsumeToken(); | |||
+ // Consume colon. | |||
+ ConsumeToken(); | |||
+ | |||
+ ExprResult IntExpr = | |||
+ getActions().CorrectDelayedTy | |||
+ if (IntExpr.isInvalid()) | |||
+ return true; | |||
+ | |||
+ if (ExpectAndConsume | |||
+ return true; | |||
+ } | |||
+ | |||
+ // [ queues : ] | |||
+ if (isOpenACCSpecial | |||
+ NextToken().is(tok::colon)) { | |||
+ // Consume queues. | |||
+ ConsumeToken(); | |||
+ // Consume colon. | |||
+ ConsumeToken(); | |||
+ } | |||
+ | |||
+ // OpenACC 3.3, section 2.16: | |||
+ // the term 'async-argument' means a nonnegative scalar integer expression, or | |||
+ // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined | |||
+ // in the C header file and the Fortran opacc module. | |||
+ // | |||
+ // We are parsing this simply as list of assignment expressions (to avoid | |||
+ // comma being troublesome), and will ensure it is an integral type. The | |||
+ // 'special' types are defined as macros, so we can't really check those | |||
+ // (other than perhaps as values at one point?), but the standard does say it | |||
+ // is implementation-defined to use any other negative value. | |||
+ // | |||
+ // | |||
+ bool FirstArg = true; | |||
+ while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_ope | |||
+ if (!FirstArg) { | |||
+ if (ExpectAndConsume | |||
+ return true; | |||
+ } | |||
+ FirstArg = false; | |||
+ | |||
+ ExprResult CurArg = | |||
+ getActions().CorrectDelayedTy | |||
+ | |||
+ if (CurArg.isInvalid()) | |||
+ return true; | |||
+ } | |||
+ | |||
+ return false; | |||
+} | |||
+ | |||
ExprResult Parser::ParseOpenACCIDEx | ExprResult Parser::ParseOpenACCIDEx | ||
ExprResult Res; | ExprResult Res; | ||
if (getLangOpts().CPlusPlus) { | if (getLangOpts().CPlusPlus) { | ||
@@ -340,8 +422,7 @@ void Parser::ParseOpe | |||
// specifications. First, see if we have `readonly:`, else we back-out and | // specifications. First, see if we have `readonly:`, else we back-out and | ||
// treat it like the beginning of a reference to a potentially-existing | // treat it like the beginning of a reference to a potentially-existing | ||
// `readonly` variable. | // `readonly` variable. | ||
- if (getCurToken().is(tok::identifier) && | + if (isOpenACCSpecial | ||
- getCurToken().getIdentifierInf | |||
NextToken().is(tok::colon)) { | NextToken().is(tok::colon)) { | ||
// Consume both tokens. | // Consume both tokens. | ||
ConsumeToken(); | ConsumeToken(); | ||
@@ -399,6 +480,13 @@ void Parser::ParseOpe | |||
// so we can always consume the close. | // so we can always consume the close. | ||
T.consumeClose(); | T.consumeClose(); | ||
break; | break; | ||
+ case OpenACCDirective | |||
+ // OpenACC has an optional paren-wrapped 'wait-argument'. | |||
+ if (ParseOpenACCWait | |||
+ T.skipToEnd(); | |||
+ else | |||
+ T.consumeClose(); | |||
+ break; | |||
} | } | ||
} else if (DirKind == OpenACCDirective | } else if (DirKind == OpenACCDirective | ||
// Cache's paren var-list is required, so error here if it isn't provided. | // Cache's paren var-list is required, so error here if it isn't provided. |
@@ -306,6 +306,7 @@ struct BuiltinTypeDeclB | |||
} | } | ||
TemplateParamete | TemplateParamete | ||
+ BuiltinTypeDeclB | |||
}; | }; | ||
struct TemplateParamete | struct TemplateParamete | ||
@@ -360,11 +361,19 @@ struct TemplateParamete | |||
return Builder; | return Builder; | ||
} | } | ||
}; | }; | ||
+} // namespace | |||
TemplateParamete | TemplateParamete | ||
return TemplateParamete | return TemplateParamete | ||
} | } | ||
-} // namespace | + | ||
+BuiltinTypeDeclB | |||
+BuiltinTypeDeclB | |||
+ TemplateParamete | |||
+ for (StringRef Name : Names) | |||
+ Builder.addTypeParameter | |||
+ return Builder.finalizeTemplate | |||
+} | |||
HLSLExternalSema | HLSLExternalSema | ||
@@ -390,7 +399,7 @@ void HLSLExternalSema | |||
// Force external decls in the HLSL namespace to load from the PCH. | // Force external decls in the HLSL namespace to load from the PCH. | ||
(void)HLSLNamespace->getCanonicalDecl | (void)HLSLNamespace->getCanonicalDecl | ||
defineTrivialHLS | defineTrivialHLS | ||
- | + defineHLSLTypesWithForwardDeclarations(); | ||
// This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's | // This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's | ||
// built in types inside a namespace, but we are planning to change that in | // built in types inside a namespace, but we are planning to change that in | ||
@@ -467,18 +476,32 @@ void HLSLExternalSema | |||
.Record; | .Record; | ||
} | } | ||
-void HLSLExternalSema | +/// Set up common members and attributes for buffer types | ||
+static BuiltinTypeDeclB | |||
+ ResourceClass RC, | |||
+ ResourceKind RK) { | |||
+ return BuiltinTypeDeclB | |||
+ .addHandleMember() | |||
+ .addDefaultHandle | |||
+ .annotateResource | |||
+} | |||
+ | |||
+void HLSLExternalSema | |||
CXXRecordDecl *Decl; | CXXRecordDecl *Decl; | ||
Decl = BuiltinTypeDeclB | Decl = BuiltinTypeDeclB | ||
- . | + .addSimpleTemplateParams({"element_type"}) | ||
- .addTypeParameter | |||
- .finalizeTemplate | |||
.Record; | .Record; | ||
- if (!Decl->isCompleteDefini | + onCompletion(Decl, [this](CXXRecordDecl *Decl) { | ||
- Completions.insert( | + setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, | ||
- std::make_pair(Decl->getCanonicalDecl | + ResourceKind::TypedBuffer) | ||
- std::bind(&HLSLExternalSema | + .addArraySubscrip | ||
- this, std::placeholders::_1))); | + .completeDefiniti | ||
+ }); | |||
+} | |||
+ | |||
+void HLSLExternalSema | |||
+ CompletionFuncti | |||
+ Completions.insert(std::make_pair(Record->getCanonicalDecl | |||
} | } | ||
void HLSLExternalSema | void HLSLExternalSema | ||
@@ -496,12 +519,3 @@ void HLSLExternalSema | |||
return; | return; | ||
It->second(Record); | It->second(Record); | ||
} | } | ||
- | |||
-void HLSLExternalSema | |||
- BuiltinTypeDeclB | |||
- .addHandleMember() | |||
- .addDefaultHandle | |||
- .addArraySubscrip | |||
- .annotateResource | |||
- .completeDefiniti | |||
-} |
@@ -7653,6 +7653,8 @@ static bool isValidOrderingF | |||
case AtomicExpr::AO__hip_atomic_l | case AtomicExpr::AO__hip_atomic_l | ||
case AtomicExpr::AO__atomic_load_ | case AtomicExpr::AO__atomic_load_ | ||
case AtomicExpr::AO__atomic_load: | case AtomicExpr::AO__atomic_load: | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
return OrderingCABI != llvm::AtomicOrderingCA | return OrderingCABI != llvm::AtomicOrderingCA | ||
OrderingCABI != llvm::AtomicOrderingCA | OrderingCABI != llvm::AtomicOrderingCA | ||
@@ -7661,6 +7663,8 @@ static bool isValidOrderingF | |||
case AtomicExpr::AO__hip_atomic_s | case AtomicExpr::AO__hip_atomic_s | ||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
return OrderingCABI != llvm::AtomicOrderingCA | return OrderingCABI != llvm::AtomicOrderingCA | ||
OrderingCABI != llvm::AtomicOrderingCA | OrderingCABI != llvm::AtomicOrderingCA | ||
OrderingCABI != llvm::AtomicOrderingCA | OrderingCABI != llvm::AtomicOrderingCA | ||
@@ -7737,13 +7741,19 @@ ExprResult Sema::BuildAtomi | |||
Op <= AtomicExpr::AO__opencl_atomi | Op <= AtomicExpr::AO__opencl_atomi | ||
bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_l | bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_l | ||
Op <= AtomicExpr::AO__hip_atomic_f | Op <= AtomicExpr::AO__hip_atomic_f | ||
+ bool IsScoped = Op >= AtomicExpr::AO__scoped_atomi | |||
+ Op <= AtomicExpr::AO__scoped_atomi | |||
bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_i | bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_i | ||
Op <= AtomicExpr::AO__c11_atomic_f | Op <= AtomicExpr::AO__c11_atomic_f | ||
IsOpenCL; | IsOpenCL; | ||
bool IsN = Op == AtomicExpr::AO__atomic_load_ | bool IsN = Op == AtomicExpr::AO__atomic_load_ | ||
Op == AtomicExpr::AO__atomic_store | Op == AtomicExpr::AO__atomic_store | ||
Op == AtomicExpr::AO__atomic_excha | Op == AtomicExpr::AO__atomic_excha | ||
- Op == | + Op == AtomicExpr::AO__atomic_compare_exchange_n || | ||
+ Op == AtomicExpr::AO__scoped_atomi | |||
+ Op == AtomicExpr::AO__scoped_atomi | |||
+ Op == AtomicExpr::AO__scoped_atomi | |||
+ Op == AtomicExpr::AO__scoped_atomi | |||
// Bit mask for extra allowed value types other than integers for atomic | // Bit mask for extra allowed value types other than integers for atomic | ||
// arithmetic operations. Add/sub allow pointer and floating point. Min/max | // arithmetic operations. Add/sub allow pointer and floating point. Min/max | ||
// allow floating point. | // allow floating point. | ||
@@ -7764,10 +7774,12 @@ ExprResult Sema::BuildAtomi | |||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__hip_atomic_l | case AtomicExpr::AO__hip_atomic_l | ||
case AtomicExpr::AO__atomic_load_ | case AtomicExpr::AO__atomic_load_ | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = Load; | Form = Load; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_load: | case AtomicExpr::AO__atomic_load: | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = LoadCopy; | Form = LoadCopy; | ||
break; | break; | ||
@@ -7776,12 +7788,18 @@ ExprResult Sema::BuildAtomi | |||
case AtomicExpr::AO__hip_atomic_s | case AtomicExpr::AO__hip_atomic_s | ||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
case AtomicExpr::AO__atomic_store | case AtomicExpr::AO__atomic_store | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = Copy; | Form = Copy; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__atomic_add_f | case AtomicExpr::AO__atomic_add_f | ||
case AtomicExpr::AO__atomic_sub_f | case AtomicExpr::AO__atomic_sub_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
@@ -7795,6 +7813,10 @@ ExprResult Sema::BuildAtomi | |||
case AtomicExpr::AO__atomic_fetch | case AtomicExpr::AO__atomic_fetch | ||
case AtomicExpr::AO__atomic_max_f | case AtomicExpr::AO__atomic_max_f | ||
case AtomicExpr::AO__atomic_min_f | case AtomicExpr::AO__atomic_min_f | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__c11_atomic_f | case AtomicExpr::AO__c11_atomic_f | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
@@ -7822,6 +7844,14 @@ ExprResult Sema::BuildAtomi | |||
case AtomicExpr::AO__atomic_or_fe | case AtomicExpr::AO__atomic_or_fe | ||
case AtomicExpr::AO__atomic_xor_f | case AtomicExpr::AO__atomic_xor_f | ||
case AtomicExpr::AO__atomic_nand_ | case AtomicExpr::AO__atomic_nand_ | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = Arithmetic; | Form = Arithmetic; | ||
break; | break; | ||
@@ -7829,10 +7859,12 @@ ExprResult Sema::BuildAtomi | |||
case AtomicExpr::AO__hip_atomic_e | case AtomicExpr::AO__hip_atomic_e | ||
case AtomicExpr::AO__opencl_atomi | case AtomicExpr::AO__opencl_atomi | ||
case AtomicExpr::AO__atomic_excha | case AtomicExpr::AO__atomic_excha | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = Xchg; | Form = Xchg; | ||
break; | break; | ||
case AtomicExpr::AO__atomic_excha | case AtomicExpr::AO__atomic_excha | ||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = GNUXchg; | Form = GNUXchg; | ||
break; | break; | ||
@@ -7847,12 +7879,15 @@ ExprResult Sema::BuildAtomi | |||
case AtomicExpr::AO__atomic_compa | case AtomicExpr::AO__atomic_compa | ||
case AtomicExpr::AO__atomic_compa | case AtomicExpr::AO__atomic_compa | ||
+ case AtomicExpr::AO__scoped_atomi | |||
+ case AtomicExpr::AO__scoped_atomi | |||
Form = GNUCmpXchg; | Form = GNUCmpXchg; | ||
break; | break; | ||
} | } | ||
unsigned AdjustedNumArgs = NumArgs[Form]; | unsigned AdjustedNumArgs = NumArgs[Form]; | ||
- if ((IsOpenCL || IsHIP | + if ((IsOpenCL || IsHIP || IsScoped) && | ||
+ Op != AtomicExpr::AO__opencl_atomi | |||
++AdjustedNumArgs; | ++AdjustedNumArgs; | ||
// Check we have the right number of arguments. | // Check we have the right number of arguments. | ||
if (Args.size() < AdjustedNumArgs) { | if (Args.size() < AdjustedNumArgs) { |
@@ -4085,16 +4085,13 @@ static bool hasCopyOrMoveCto | |||
return Ctx.hasSameUnqualifi | return Ctx.hasSameUnqualifi | ||
} | } | ||
-static OverloadingResult | +static OverloadingResult ResolveConstructorOverload( | ||
-ResolveConstruct | + Sema &S, SourceLocation DeclLoc, MultiExprArg Args, | ||
- MultiExprArg Args, | + OverloadCandidat | ||
- OverloadCandidat | + DeclContext::lookup_result Ctors, OverloadCandidat | ||
- QualType DestType, | + bool CopyInitializing | ||
- DeclContext::lookup_result Ctors, | + bool IsListInit, bool RequireActualCon | ||
- OverloadCandidat | + bool SecondStepOfCopy | ||
- bool CopyInitializing | |||
- bool OnlyListConstruc | |||
- bool SecondStepOfCopy | |||
CandidateSet.clear(OverloadCandidat | CandidateSet.clear(OverloadCandidat | ||
CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace()); | CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace()); | ||
@@ -4157,7 +4154,7 @@ ResolveConstruct | |||
// Note: SecondStepOfCopy | // Note: SecondStepOfCopy | ||
// evaluating whether to produce a C++98 compatibility warning. | // evaluating whether to produce a C++98 compatibility warning. | ||
if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && | if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && | ||
- !SecondStepOfCopyInit) { | + !RequireActualConstructor && !SecondStepOfCopyInit) { | ||
Expr *Initializer = Args[0]; | Expr *Initializer = Args[0]; | ||
auto *SourceRD = Initializer->getType()->getAsCXXRecordDe | auto *SourceRD = Initializer->getType()->getAsCXXRecordDe | ||
if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) { | if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) { | ||
@@ -4225,6 +4222,12 @@ static void TryConstructorIn | |||
return; | return; | ||
} | } | ||
+ bool RequireActualCon | |||
+ !(Entity.getKind() != InitializedEntit | |||
+ Entity.getKind() != InitializedEntit | |||
+ Entity.getKind() != | |||
+ InitializedEntit | |||
+ | |||
// C++17 [dcl.init]p17: | // C++17 [dcl.init]p17: | ||
// - If the initializer expression is a prvalue and the cv-unqualified | // - If the initializer expression is a prvalue and the cv-unqualified | ||
// version of the source type is the same class as the class of the | // version of the source type is the same class as the class of the | ||
@@ -4234,11 +4237,7 @@ static void TryConstructorIn | |||
// class or delegating to another constructor from a mem-initializer. | // class or delegating to another constructor from a mem-initializer. | ||
// ObjC++: Lambda captured by the block in the lambda to block conversion | // ObjC++: Lambda captured by the block in the lambda to block conversion | ||
// should avoid copy elision. | // should avoid copy elision. | ||
- if (S.getLangOpts().CPlusPlus17 && | + if (S.getLangOpts().CPlusPlus17 && !RequireActualConstructor && | ||
- Entity.getKind() != InitializedEntit | |||
- Entity.getKind() != InitializedEntit | |||
- Entity.getKind() != | |||
- InitializedEntit | |||
UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() && | UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() && | ||
S.Context.hasSameUnqualifi | S.Context.hasSameUnqualifi | ||
// Convert qualifications if necessary. | // Convert qualifications if necessary. | ||
@@ -4286,11 +4285,10 @@ static void TryConstructorIn | |||
// If the initializer list has no elements and T has a default constructor, | // If the initializer list has no elements and T has a default constructor, | ||
// the first phase is omitted. | // the first phase is omitted. | ||
if (!(UnwrappedArgs.empty() && S.LookupDefaultCon | if (!(UnwrappedArgs.empty() && S.LookupDefaultCon | ||
- Result = ResolveConstructorOverload( | + Result = ResolveConstructorOverload( | ||
- CandidateSet, DestType, Ctors, Best, | + S, Kind.getLocation(), Args, CandidateSet, DestType, Ctors, Best, | ||
- | + CopyInitialization, AllowExplicit, | ||
- /*OnlyListConstruc | + /*OnlyListConstruc | ||
- IsListInit); | |||
} | } | ||
// C++11 [over.match.list]p1: | // C++11 [over.match.list]p1: | ||
@@ -4300,11 +4298,10 @@ static void TryConstructorIn | |||
// elements of the initializer list. | // elements of the initializer list. | ||
if (Result == OR_No_Viable_Fun | if (Result == OR_No_Viable_Fun | ||
AsInitializerLis | AsInitializerLis | ||
- Result = ResolveConstructorOverload( | + Result = ResolveConstructorOverload( | ||
- CandidateSet, DestType, Ctors, Best, | + S, Kind.getLocation(), UnwrappedArgs, CandidateSet, DestType, Ctors, | ||
- | + Best, CopyInitialization, AllowExplicit, | ||
- /*OnlyListConstruc | + /*OnlyListConstruc | ||
- IsListInit); | |||
} | } | ||
if (Result) { | if (Result) { | ||
Sequence.SetOverloadFailu | Sequence.SetOverloadFailu | ||
@@ -6778,6 +6775,7 @@ static ExprResult CopyObject(Sema &S, | |||
S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best, | S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best, | ||
/*CopyInitializing | /*CopyInitializing | ||
/*OnlyListConstruc | /*OnlyListConstruc | ||
+ /*RequireActualCon | |||
/*SecondStepOfCopy | /*SecondStepOfCopy | ||
case OR_Success: | case OR_Success: | ||
break; | break; | ||
@@ -6920,6 +6918,7 @@ static void CheckCXX98Compat | |||
S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best, | S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best, | ||
/*CopyInitializing | /*CopyInitializing | ||
/*OnlyListConstruc | /*OnlyListConstruc | ||
+ /*RequireActualCon | |||
/*SecondStepOfCopy | /*SecondStepOfCopy | ||
PartialDiagnosti | PartialDiagnosti |
@@ -1327,6 +1327,9 @@ Sema::ActOnFinis | |||
} | } | ||
} | } | ||
+ if (!TheDefaultStmt) | |||
+ Diag(SwitchLoc, diag::warn_switch_defa | |||
+ | |||
if (!HasDependentValu | if (!HasDependentValu | ||
// If we don't have a default statement, check whether the | // If we don't have a default statement, check whether the | ||
// condition is constant. | // condition is constant. |
@@ -1712,6 +1712,8 @@ class ConstraintRefers | |||
// Friend, likely because it was referred to without its template arguments. | // Friend, likely because it was referred to without its template arguments. | ||
void CheckIfContainin | void CheckIfContainin | ||
CheckingRD = CheckingRD->getMostRecentDec | CheckingRD = CheckingRD->getMostRecentDec | ||
+ if (!CheckingRD->isTemplated()) | |||
+ return; | |||
for (const DeclContext *DC = Friend->getLexicalDeclCo | for (const DeclContext *DC = Friend->getLexicalDeclCo | ||
DC && !DC->isFileContext(); DC = DC->getParent()) | DC && !DC->isFileContext(); DC = DC->getParent()) |
@@ -810,6 +810,10 @@ void Sema::PrintInsta | |||
Diags.Report(Active->PointOfInstantia | Diags.Report(Active->PointOfInstantia | ||
diag::note_template_ns | diag::note_template_ns | ||
<< FD << Active->InstantiationRan | << FD << Active->InstantiationRan | ||
+ } else if (ClassTemplateDec | |||
+ Diags.Report(Active->PointOfInstantia | |||
+ diag::note_template_cl | |||
+ << CTD << Active->InstantiationRan | |||
} else { | } else { | ||
Diags.Report(Active->PointOfInstantia | Diags.Report(Active->PointOfInstantia | ||
diag::note_template_ty | diag::note_template_ty |
@@ -344,7 +344,7 @@ BitwiseShiftVali | |||
} // anonymous namespace | } // anonymous namespace | ||
class BitwiseShiftChec | class BitwiseShiftChec | ||
- mutable std::unique_ptr<BugType> BTPtr; | + BugType BT{this, "Bitwise shift", "Suspicious operation"}; | ||
public: | public: | ||
void checkPreStmt(const BinaryOperator *B, CheckerContext &Ctx) const { | void checkPreStmt(const BinaryOperator *B, CheckerContext &Ctx) const { | ||
@@ -353,11 +353,7 @@ public: | |||
if (Op != BO_Shl && Op != BO_Shr) | if (Op != BO_Shl && Op != BO_Shr) | ||
return; | return; | ||
- if (!BTPtr) | + BitwiseShiftVali | ||
- BTPtr = std::make_unique<BugType>(this, "Bitwise shift", | |||
- "Suspicious operation"); | |||
- | |||
- BitwiseShiftVali | |||
} | } | ||
bool Pedantic = false; | bool Pedantic = false; |
@@ -22,10 +22,12 @@ | |||
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRe | #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRe | ||
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" | #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" | ||
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" | #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" | ||
+#include "llvm/Support/FormatVariadic.h" | |||
#include <optional> | #include <optional> | ||
using namespace clang; | using namespace clang; | ||
using namespace ento; | using namespace ento; | ||
+using llvm::formatv; | |||
namespace { | namespace { | ||
// This evaluator checks two SVals for equality. The first SVal is provided via | // This evaluator checks two SVals for equality. The first SVal is provided via | ||
@@ -87,17 +89,22 @@ void EnumCastOutOfRan | |||
EnumValueCastOut | EnumValueCastOut | ||
new BugType(this, "Enum cast out of range")); | new BugType(this, "Enum cast out of range")); | ||
- llvm::SmallString<128> Msg{"The value provided to the cast expression is " | + std::string ValueStr = "", NameStr = "the enum"; | ||
- "not in the valid range of values for "}; | + | ||
- StringRef EnumName{E->getName()}; | + // Try to add details to the message: | ||
- if (EnumName.empty()) { | + const auto ConcreteValue = | ||
- Msg += "the enum"; | + C.getSVal(CE->getSubExpr()).getAs<nonloc::ConcreteInt>(); | ||
- } else { | + if (ConcreteValue) { | ||
- Msg += '\''; | + ValueStr = formatv(" '{0}'", ConcreteValue->getValue()); | ||
- Msg += EnumName; | + } | ||
- Msg += '\''; | + if (StringRef EnumName{E->getName()}; !EnumName.empty()) { | ||
+ NameStr = formatv("'{0}'", EnumName); | |||
} | } | ||
+ std::string Msg = formatv("The value{0} provided to the cast expression is " | |||
+ "not in the valid range of values for {1}", | |||
+ ValueStr, NameStr); | |||
+ | |||
auto BR = std::make_unique<PathSensitiveBug | auto BR = std::make_unique<PathSensitiveBug | ||
Msg, N); | Msg, N); | ||
bugreporter::trackExpressionV | bugreporter::trackExpressionV |
@@ -13,8 +13,6 @@ | |||
// EMPTY: ClassTemplateDec | // EMPTY: ClassTemplateDec | ||
// EMPTY-NEXT: TemplateTypeParm | // EMPTY-NEXT: TemplateTypeParm | ||
-// EMPTY-NEXT: TemplateArgument | |||
-// EMPTY-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float' | |||
// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer | // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer | ||
// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final | // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final | ||
@@ -33,8 +31,6 @@ RWBuffer<float> Buffer; | |||
// CHECK: ClassTemplateDec | // CHECK: ClassTemplateDec | ||
// CHECK-NEXT: TemplateTypeParm | // CHECK-NEXT: TemplateTypeParm | ||
-// CHECK-NEXT: TemplateArgument | |||
-// CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float' | |||
// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition | // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition | ||
// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final | // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final |
@@ -6,7 +6,7 @@ | |||
// Make sure PCH works by using function declared in PCH header and declare a RWBuffer in current file. | // Make sure PCH works by using function declared in PCH header and declare a RWBuffer in current file. | ||
// CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)' | // CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)' | ||
-// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:10:1, col:23> col:23 Buffer | +// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:10:1, col:23> col:23 Buffer 'hlsl::RWBuffer<float>' | ||
hlsl::RWBuffer<float> Buffer; | hlsl::RWBuffer<float> Buffer; | ||
float2 bar(float2 a, float2 b) { | float2 bar(float2 a, float2 b) { |
@@ -5,9 +5,9 @@ | |||
// Make sure PCH works by using function declared in PCH header. | // Make sure PCH works by using function declared in PCH header. | ||
// CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)' | // CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)' | ||
// Make sure buffer defined in PCH works. | // Make sure buffer defined in PCH works. | ||
-// CHECK:VarDecl 0x{{[0-9a-f]+}} <line:6:1, col:17> col:17 imported Buf | +// CHECK:VarDecl 0x{{[0-9a-f]+}} <line:6:1, col:17> col:17 imported Buf 'RWBuffer<float>' | ||
// Make sure declare a RWBuffer in current file works. | // Make sure declare a RWBuffer in current file works. | ||
-// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:11:1, col:23> col:23 Buf2 | +// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:11:1, col:23> col:23 Buf2 'hlsl::RWBuffer<float>' | ||
hlsl::RWBuffer<float> Buf2; | hlsl::RWBuffer<float> Buf2; | ||
float2 bar(float2 a, float2 b) { | float2 bar(float2 a, float2 b) { |
@@ -23,15 +23,15 @@ float foo() { | |||
return a + b; | return a + b; | ||
} | } | ||
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV | +// CHECK: VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV 'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit | ||
-// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> | +// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<float>' 'void ()' | ||
// CHECK-NEXT:-HLSLResourceBind | // CHECK-NEXT:-HLSLResourceBind | ||
RWBuffer<float> UAV : register(u3); | RWBuffer<float> UAV : register(u3); | ||
-// CHECK: -VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV1 | +// CHECK: -VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV1 'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit | ||
-// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> | +// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<float>' 'void ()' | ||
// CHECK-NEXT:-HLSLResourceBind | // CHECK-NEXT:-HLSLResourceBind | ||
-// CHECK-NEXT:-VarDecl 0x{{[0-9a-f]+}} <col:1, col:38> col:38 UAV2 | +// CHECK-NEXT:-VarDecl 0x{{[0-9a-f]+}} <col:1, col:38> col:38 UAV2 'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit | ||
-// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:38> | +// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:38> 'RWBuffer<float>':'hlsl::RWBuffer<float>' 'void ()' | ||
// CHECK-NEXT:-HLSLResourceBind | // CHECK-NEXT:-HLSLResourceBind | ||
RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); | RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); |
@@ -331,3 +331,11 @@ namespace bitreverse { | |||
char bitreverse3[__builtin_bitrev | char bitreverse3[__builtin_bitrev | ||
char bitreverse4[__builtin_bitrev | char bitreverse4[__builtin_bitrev | ||
} | } | ||
+ | |||
+namespace expect { | |||
+ constexpr int a() { | |||
+ return 12; | |||
+ } | |||
+ static_assert(__builtin_expect | |||
+ static_assert(__builtin_expect | |||
+} |
@@ -43,115 +43,115 @@ struct S { | |||
}; | }; | ||
void unscopedUnspecif | void unscopedUnspecif | ||
- unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
unscoped_unspeci | unscoped_unspeci | ||
unscoped_unspeci | unscoped_unspeci | ||
- unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
- unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
- unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
unscoped_unspeci | unscoped_unspeci | ||
unscoped_unspeci | unscoped_unspeci | ||
- unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
unscoped_unspeci | unscoped_unspeci | ||
- unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
} | } | ||
void unscopedSpecifie | void unscopedSpecifie | ||
- unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
unscoped_specifi | unscoped_specifi | ||
unscoped_specifi | unscoped_specifi | ||
- unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
- unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
- unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
unscoped_specifi | unscoped_specifi | ||
unscoped_specifi | unscoped_specifi | ||
- unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
unscoped_specifi | unscoped_specifi | ||
- unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
} | } | ||
void scopedUnspecifie | void scopedUnspecifie | ||
- scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
scoped_unspecifi | scoped_unspecifi | ||
scoped_unspecifi | scoped_unspecifi | ||
- scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
- scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
- scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
scoped_unspecifi | scoped_unspecifi | ||
scoped_unspecifi | scoped_unspecifi | ||
- scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
scoped_unspecifi | scoped_unspecifi | ||
- scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
} | } | ||
void scopedSpecified() { | void scopedSpecified() { | ||
- scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
scoped_specified | scoped_specified | ||
scoped_specified | scoped_specified | ||
- scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
- scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
- scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
scoped_specified | scoped_specified | ||
scoped_specified | scoped_specified | ||
- scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
scoped_specified | scoped_specified | ||
- scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
} | } | ||
void unscopedUnspecif | void unscopedUnspecif | ||
- unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
unscoped_unspeci | unscoped_unspeci | ||
unscoped_unspeci | unscoped_unspeci | ||
- unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
- unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
- unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
unscoped_unspeci | unscoped_unspeci | ||
unscoped_unspeci | unscoped_unspeci | ||
- unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
unscoped_unspeci | unscoped_unspeci | ||
- unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
} | } | ||
void unscopedSpecifie | void unscopedSpecifie | ||
- unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
unscoped_specifi | unscoped_specifi | ||
unscoped_specifi | unscoped_specifi | ||
- unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
- unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
- unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
unscoped_specifi | unscoped_specifi | ||
unscoped_specifi | unscoped_specifi | ||
- unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
unscoped_specifi | unscoped_specifi | ||
- unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | + unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}} | ||
} | } | ||
void scopedUnspecifie | void scopedUnspecifie | ||
- scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
scoped_unspecifi | scoped_unspecifi | ||
scoped_unspecifi | scoped_unspecifi | ||
- scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
- scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
- scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
scoped_unspecifi | scoped_unspecifi | ||
scoped_unspecifi | scoped_unspecifi | ||
- scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
scoped_unspecifi | scoped_unspecifi | ||
- scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | + scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}} | ||
} | } | ||
void scopedSpecifiedC | void scopedSpecifiedC | ||
- scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
scoped_specified | scoped_specified | ||
scoped_specified | scoped_specified | ||
- scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
- scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
- scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
scoped_specified | scoped_specified | ||
scoped_specified | scoped_specified | ||
- scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
scoped_specified | scoped_specified | ||
- scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
} | } | ||
unscoped_unspeci | unscoped_unspeci | ||
@@ -194,13 +194,13 @@ void rangeConstrained | |||
void rangeConstrained | void rangeConstrained | ||
if (input >= 3 && input <= 3) | if (input >= 3 && input <= 3) | ||
- auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | + auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}} | ||
} | } | ||
void enumBitFieldAssi | void enumBitFieldAssi | ||
S s; | S s; | ||
s.E = static_cast<unscoped_unspeci | s.E = static_cast<unscoped_unspeci | ||
- s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | + s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}} | ||
} | } | ||
@@ -0,0 +1,83 @@ | |||
+// RUN: %clang_cc1 -x c -std=c2x -fsyntax-only -verify %s | |||
+// RUN: %clang_cc1 -x c -std=c2x -E -DPP_ONLY=1 %s | FileCheck %s --strict-whitespace | |||
+ | |||
+/* WG14 N2836: Clang 15 | |||
+ * Identifier Syntax using Unicode Standard Annex 31 | |||
+ */ | |||
+ | |||
+/* WG14 N2939: Clang 15 | |||
+ * Identifier Syntax Fixes | |||
+ */ | |||
+ | |||
+// Some of the tests below are derived from clang/test/Lexer/unicode.c. | |||
+ | |||
+// This file contains Unicode characters; please do not "fix" them! | |||
+ | |||
+// No diagnostics for pragma directives. | |||
+#pragma mark ¡Unicode! | |||
+ | |||
+// lone non-identifier characters are allowed in preprocessing. | |||
+#define COPYRIGHT Copyright © 2012 | |||
+#define XSTR(X) #X | |||
+#define STR(X) XSTR(X) | |||
+ | |||
+static const char *copyright = STR(COPYRIGHT); // no-warning | |||
+// CHECK: static const char *copyright = "Copyright © {{2012}}"; | |||
+ | |||
+#if PP_ONLY | |||
+COPYRIGHT | |||
+// CHECK: Copyright © {{2012}} | |||
+#endif | |||
+ | |||
+// The characters in the following identifiers are no longer valid as either | |||
+// start or continuation characters as of C23. These are taken from section 1 | |||
+// of N2836. | |||
+extern int \N{CONSTRUCTION WORKER}; // expected-error {{expected identifier or '('}} | |||
+extern int X\N{CONSTRUCTION WORKER}; // expected-error {{character <U+1F477> not allowed in an identifier}} | |||
+extern int \U0001F477; // expected-error {{expected identifier or '('}} | |||
+extern int X\U0001F477; // expected-error {{character <U+1F477> not allowed in an identifier}} | |||
+extern int 👷; // expected-error {{unexpected character <U+1F477>}} \ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X👷; // expected-error {{character <U+1F477> not allowed in an identifier}} | |||
+extern int 🕐; // expected-error {{unexpected character <U+1F550>}} \ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X🕐; // expected-error {{character <U+1F550> not allowed in an identifier}} | |||
+extern int 💀; // expected-error {{unexpected character <U+1F480>}} \ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X💀; // expected-error {{character <U+1F480> not allowed in an identifier}} | |||
+extern int 👊; // expected-error {{unexpected character <U+1F44A>}} \ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X👊; // expected-error {{character <U+1F44A> not allowed in an identifier}} | |||
+extern int 🚀; // expected-error {{unexpected character <U+1F680>}} \ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X🚀; // expected-error {{character <U+1F680> not allowed in an identifier}} | |||
+extern int 😀; // expected-error {{unexpected character <U+1F600>}} \ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X😀; // expected-error {{character <U+1F600> not allowed in an identifier}} | |||
+ | |||
+// The characters in the following identifiers are not allowed as start | |||
+// characters, but are allowed as continuation characters. | |||
+extern int \N{ARABIC-INDIC DIGIT ZERO}; // expected-error {{expected identifier or '('}} | |||
+extern int X\N{ARABIC-INDIC DIGIT ZERO}; | |||
+extern int \u0661; // expected-error {{expected identifier or '('}} | |||
+extern int X\u0661; | |||
+extern int ٢; // expected-error {{character <U+0662> not allowed at the start of an identifier}} \\ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X٠; | |||
+ | |||
+// The characters in the following identifiers are not valid start or | |||
+// continuation characters in the standard, but are accepted as a conforming | |||
+// extension. | |||
+extern int \N{SUPERSCRIPT ZERO}; // expected-error {{expected identifier or '('}} | |||
+extern int X\N{SUPERSCRIPT ZERO}; // expected-warning {{mathematical notation character <U+2070> in an identifier is a Clang extension}} | |||
+extern int \u00B9; // expected-error {{expected identifier or '('}} | |||
+extern int X\u00B9; // expected-warning {{mathematical notation character <U+00B9> in an identifier is a Clang extension}} | |||
+extern int ²; // expected-error {{character <U+00B2> not allowed at the start of an identifier}} \\ | |||
+ // expected-warning {{declaration does not declare anything}} | |||
+extern int X²; // expected-warning {{mathematical notation character <U+00B2> in an identifier is a Clang extension}} | |||
+extern int \N{PARTIAL DIFFERENTIAL}; // expected-warning {{mathematical notation character <U+2202> in an identifier is a Clang extension}} | |||
+extern int X\N{PARTIAL DIFFERENTIAL}; // expected-warning {{mathematical notation character <U+2202> in an identifier is a Clang extension}} | |||
+extern int \u2207; // expected-warning {{mathematical notation character <U+2207> in an identifier is a Clang extension}} | |||
+extern int X\u2207; // expected-warning {{mathematical notation character <U+2207> in an identifier is a Clang extension}} | |||
+extern int ∞; // expected-warning {{mathematical notation character <U+221E> in an identifier is a Clang extension}} | |||
+extern int X∞; // expected-warning {{mathematical notation character <U+221E> in an identifier is a Clang extension}} |
@@ -1,9 +1,9 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++20 %s - | +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++23 %s - | +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
namespace std { | namespace std { | ||
__extension__ typedef __SIZE_TYPE__ size_t; | __extension__ typedef __SIZE_TYPE__ size_t; | ||
@@ -18,30 +18,40 @@ namespace dr1004 { // dr1004: 5 | |||
template<typename> struct A {}; | template<typename> struct A {}; | ||
template<typename> struct B1 {}; | template<typename> struct B1 {}; | ||
template<template<typename> class> struct B2 {}; | template<template<typename> class> struct B2 {}; | ||
- template<typename X> void f(); // | + template<typename X> void f(); // #dr1004-f-1 | ||
- template<template<typename> class X> void f(); // | + template<template<typename> class X> void f(); // #dr1004-f-2 | ||
- template<template<typename> class X> void g(); // | + template<template<typename> class X> void g(); // #dr1004-g-1 | ||
- template<typename X> void g(); // | + template<typename X> void g(); // #dr1004-g-2 | ||
struct C : A<int> { | struct C : A<int> { | ||
B1<A> b1a; | B1<A> b1a; | ||
B2<A> b2a; | B2<A> b2a; | ||
void h() { | void h() { | ||
- f<A>(); | + f<A>(); | ||
- | + // expected-error@-1 {{call to 'f' is ambiguous}} | ||
+ // expected-note@#dr1004-f-1 {{candidate function [with X = dr1004::A<int>]}} | |||
+ // expected-note@#dr1004-f-2 {{candidate function [with X = dr1004::A]}} | |||
+ g<A>(); | |||
+ // expected-error@-1 {{call to 'g' is ambiguous}} | |||
+ // expected-note@#dr1004-g-1 {{candidate function [with X = dr1004::A]}} | |||
+ // expected-note@#dr1004-g-2 {{candidate function [with X = dr1004::A<int>]}} | |||
} | } | ||
}; | }; | ||
// This example (from the standard) is actually ill-formed, because | // This example (from the standard) is actually ill-formed, because | ||
// name lookup of "T::template A" names the constructor. | // name lookup of "T::template A" names the constructor. | ||
- template<class T, template<class> class U = T::template A> struct Third { }; | + template<class T, template<class> class U = T::template A> struct Third { }; | ||
- Third<A<int> > t; // expected-note {{in instantiation of default argument}} | + // expected-error@-1 {{is a constructor name}} | ||
+ // expected-note@#dr1004-t {{in instantiation of default argument}} | |||
+ Third<A<int> > t; // #dr1004-t | |||
} | } | ||
namespace dr1042 { // dr1042: 3.5 | namespace dr1042 { // dr1042: 3.5 | ||
#if __cplusplus >= 201402L | #if __cplusplus >= 201402L | ||
// C++14 added an attribute that we can test the semantics of. | // C++14 added an attribute that we can test the semantics of. | ||
- using foo [[deprecated]] = int; // expected-note {{'foo' has been explicitly marked deprecated here}} | + using foo [[deprecated]] = int; // #dr1042-using | ||
- foo f = 12; | + foo f = 12; | ||
+ // since-cxx14-warning@-1 {{'foo' is deprecated}} | |||
+ // since-cxx14-note@#dr1042-using {{'foo' has been explicitly marked deprecated here}} | |||
#elif __cplusplus >= 201103L | #elif __cplusplus >= 201103L | ||
// C++11 did not have any attributes that could be applied to an alias | // C++11 did not have any attributes that could be applied to an alias | ||
// declaration, so the best we can test is that we accept an empty attribute | // declaration, so the best we can test is that we accept an empty attribute | ||
@@ -76,7 +86,8 @@ namespace dr1054 { // dr1054: no | |||
// which copy-initializes a temporary from 'a'. Therefore this is | // which copy-initializes a temporary from 'a'. Therefore this is | ||
// ill-formed because A does not have a volatile copy constructor. | // ill-formed because A does not have a volatile copy constructor. | ||
// (We might want to track this aspect under dr1383 instead?) | // (We might want to track this aspect under dr1383 instead?) | ||
- a; // expected-warning {{assign into a variable to force a volatile load}} | + a; | ||
+ // expected-warning@-1 {{expression result unused; assign into a variable to force a volatile load}} | |||
} | } | ||
} | } | ||
@@ -1,30 +1,30 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++2a %s - | +// RUN: %clang_cc1 -std=c++2a %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-namespace dr1111 { // dr1111: | +namespace dr1111 { // dr1111: 3.2 | ||
namespace example1 { | namespace example1 { | ||
-template <typename> struct set; | +template <typename> struct set; // #dr1111-struct-set | ||
struct X { | struct X { | ||
- template <typename T> void set(const T &value); | + template <typename T> void set(const T &value); // #dr1111-func-set | ||
}; | }; | ||
void foo() { | void foo() { | ||
X x; | X x; | ||
-#pragma clang diagnostic push | + // FIXME: should we backport C++11 behavior? | ||
-#if __cplusplus < 201103L | |||
-#pragma clang diagnostic ignored "-Wambiguous-member-template" | |||
-#endif | |||
x.set<double>(3.2); | x.set<double>(3.2); | ||
-#pragma clang diagnostic pop | + // cxx98-error@-1 {{lookup of 'set' in member access expression is ambiguous; using member of 'X'}} | ||
+ // cxx98-note@#dr1111-func-set {{lookup in the object type 'X' refers here}} | |||
+ // cxx98-note@#dr1111-struct-set {{lookup from the current scope refers here}} | |||
} | } | ||
struct Y {}; | struct Y {}; | ||
void bar() { | void bar() { | ||
Y y; | Y y; | ||
- y.set<double>(3.2); | + y.set<double>(3.2); | ||
+ // expected-error@-1 {{no member named 'set' in 'dr1111::example1::Y'}} | |||
} | } | ||
} // namespace example1 | } // namespace example1 | ||
@@ -46,8 +46,10 @@ void baz() { | |||
namespace dr1113 { // dr1113: partial | namespace dr1113 { // dr1113: partial | ||
namespace named { | namespace named { | ||
- extern int a; // | + extern int a; // #dr1113-a | ||
- static int a; | + static int a; | ||
+ // expected-error@-1 {{static declaration of 'a' follows non-static}} | |||
+ // expected-note@#dr1113-a {{previous declaration is here}} | |||
} | } | ||
namespace { | namespace { | ||
extern int a; | extern int a; |
@@ -1,9 +1,9 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++20 %s - | +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++23 %s - | +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors | ||
// dr1200: na | // dr1200: na | ||
@@ -40,28 +40,33 @@ struct S { | |||
S* operator()(); | S* operator()(); | ||
int N; | int N; | ||
int M; | int M; | ||
-#if __cplusplus | +#if __cplusplus >= 202302L | ||
template <typename T> | template <typename T> | ||
static constexpr auto V = 0; | static constexpr auto V = 0; | ||
void f(char); | void f(char); | ||
void f(int); | void f(int); | ||
void mem(S s) { | void mem(S s) { | ||
- auto(s)()->M; //expected-warning {{expression result unused}} | + auto(s)()->M; | ||
- | + // since-cxx23-warning@-1 {{expression result unused}} | ||
+ auto(s)()->V<int>; | |||
+ // since-cxx23-warning@-1 {{expression result unused}} | |||
auto(s)()->f(0); | auto(s)()->f(0); | ||
} | } | ||
#endif | #endif | ||
}; | }; | ||
void f(S s) { | void f(S s) { | ||
{ | { | ||
-#if __cplusplus | +#if __cplusplus >= 202302L | ||
- auto(s)()->N; //expected-warning {{expression result unused}} | + auto(s)()->N; | ||
+ //since-cxx23-warning@-1 {{expression result unused}} | |||
#endif | #endif | ||
auto(s)()->M; | auto(s)()->M; | ||
} | } | ||
{ | { | ||
- S(s)()->N; //expected-warning {{expression result unused}} | + S(s)()->N; | ||
- | + // since-cxx11-warning@-1 {{expression result unused}} | ||
+ S(s)()->M; | |||
+ // since-cxx11-warning@-1 {{expression result unused}} | |||
} | } | ||
} | } | ||
@@ -74,23 +79,27 @@ void g() { | |||
A a(B ()->C); | A a(B ()->C); | ||
A b(auto ()->C); | A b(auto ()->C); | ||
static_assert(sizeof(B ()->C[1] == sizeof(int)), ""); | static_assert(sizeof(B ()->C[1] == sizeof(int)), ""); | ||
- sizeof(auto () -> C[1]); // expected-error{{function cannot return array type 'C[1]'}} | + sizeof(auto () -> C[1]); | ||
+ // since-cxx11-error@-1 {{function cannot return array type 'C[1]' (aka 'dr1223::BB[1]')}} | |||
} | } | ||
} | } | ||
#endif | #endif | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
-namespace dr1227 { // dr1227: | +namespace dr1227 { // dr1227: 3.0 | ||
-template <class T> struct A { using X = typename T::X; }; | +template <class T> struct A { using X = typename T::X; }; | ||
+// since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}} | |||
+// since-cxx11-note@#dr1227-g {{in instantiation of template class 'dr1227::A<int>' requested here}} | |||
+// since-cxx11-note@#dr1227-g-int {{while substituting explicitly-specified template arguments into function template 'g'}} | |||
template <class T> typename T::X f(typename A<T>::X); | template <class T> typename T::X f(typename A<T>::X); | ||
template <class T> void f(...) { } | template <class T> void f(...) { } | ||
-template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{in instantiation of template class 'dr1227::A<int>' requested here}} | +template <class T> auto g(typename A<T>::X) -> typename T::X; // #dr1227-g | ||
template <class T> void g(...) { } | template <class T> void g(...) { } | ||
void h() { | void h() { | ||
f<int>(0); // OK, substituting return type causes deduction to fail | f<int>(0); // OK, substituting return type causes deduction to fail | ||
- g<int>(0); // expected-note {{while substituting explicitly-specified template arguments into function template 'g'}} | + g<int>(0); // #dr1227-g-int | ||
} | } | ||
} | } | ||
#endif | #endif | ||
@@ -109,15 +118,21 @@ struct Derived : Base { | |||
namespace dr1265 { // dr1265: 5 | namespace dr1265 { // dr1265: 5 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- auto a = 0, b() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}} | + auto a = 0, b() -> int; | ||
- | + // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}} | ||
- auto e() -> int, f() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}} | + auto b() -> int, d = 0; | ||
+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}} | |||
+ auto e() -> int, f() -> int; | |||
+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}} | |||
#endif | #endif | ||
#if __cplusplus >= 201402L | #if __cplusplus >= 201402L | ||
- auto g(), h = 0; | + auto g(), h = 0; | ||
- | + // since-cxx14-error@-1 {{function with deduced return type must be the only declaration in its group}} | ||
- auto k(), l(); // expected-error {{function with deduced return type must be the only declaration in its group}} | + auto i = 0, j(); | ||
+ // since-cxx14-error@-1 {{function with deduced return type must be the only declaration in its group}} | |||
+ auto k(), l(); | |||
+ // since-cxx14-error@-1 {{function with deduced return type must be the only declaration in its group}} | |||
#endif | #endif | ||
} | } | ||
@@ -130,16 +145,16 @@ namespace dr1295 { // dr1295: 4 | |||
X x = {1}; | X x = {1}; | ||
- unsigned const &r1 = static_cast<X &&>(x).bitfield; | + unsigned const &r1 = static_cast<X &&>(x).bitfield; | ||
- unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); // expected-error 0-1{{C++11}} | + // cxx98-error@-1 {{rvalue references are a C++11 extension}} | ||
+ unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); | |||
+ // cxx98-error@-1 {{rvalue references are a C++11 extension}} | |||
- template<unsigned &r> struct Y {}; | + template<unsigned &r> struct Y {}; // #dr1295-Y | ||
- Y<x.bitfield> y; | + Y<x.bitfield> y; // #dr1295-y | ||
-#if __cplusplus <= 201402L | + // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}} | ||
- // expected-error@-2 {{does not refer to any declaration}} expected-note@-3 {{here}} | + // cxx98-14-note@#dr1295-Y {{template parameter is declared here}} | ||
-#else | + // since-cxx17-error@#dr1295-y {{non-type template argument refers to subobject 'x.bitfield'}} | ||
- // expected-error@-4 {{refers to subobject}} | |||
-#endif | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
const unsigned other = 0; | const unsigned other = 0; |
@@ -1,7 +1,10 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,cxx11-14,cxx98-14,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-17,cxx11-14,since-cxx14,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx11-17,since-cxx14,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | |||
__extension__ typedef __SIZE_TYPE__ size_t; | __extension__ typedef __SIZE_TYPE__ size_t; | ||
@@ -14,11 +17,13 @@ namespace std { | |||
} | } | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
-namespace dr1305 { // dr1305: | +namespace dr1305 { // dr1305: 3.0 | ||
-struct Incomplete; // expected-note {{forward declaration of 'dr1305::Incomplete'}} | +struct Incomplete; // #dr1305-Incomplete | ||
struct Complete {}; | struct Complete {}; | ||
-int incomplete = alignof(Incomplete(&)[]); | +int incomplete = alignof(Incomplete(&)[]); | ||
+// since-cxx11-error@-1 {{invalid application of 'alignof' to an incomplete type 'Incomplete'}} | |||
+// since-cxx11-note@#dr1305-Incomplete {{forward declaration of 'dr1305::Incomplete'}} | |||
int complete = alignof(Complete(&)[]); | int complete = alignof(Complete(&)[]); | ||
} | } | ||
#endif | #endif | ||
@@ -36,9 +41,11 @@ void caller() { | |||
} // namespace dr1307 | } // namespace dr1307 | ||
namespace dr1310 { // dr1310: 5 | namespace dr1310 { // dr1310: 5 | ||
- struct S {} * sp = new S::S; | + struct S {} * sp = new S::S; | ||
+ // expected-error@-1 {{qualified reference to 'S' is a constructor name rather than a type in this context}} | |||
void f() { | void f() { | ||
- S::S(a); // expected-error {{qualified reference to 'S' is a constructor name}} | + S::S(a); | ||
+ // expected-error@-1 {{qualified reference to 'S' is a constructor name rather than a type in this context}} | |||
} | } | ||
struct T { int n; typedef int U; typedef T V; }; | struct T { int n; typedef int U; typedef T V; }; | ||
int k = T().T::T::n; | int k = T().T::T::n; | ||
@@ -64,39 +71,67 @@ namespace dr1310 { // dr1310: 5 | |||
template<typename T> struct W : WBase<T> { typedef int X; int n; }; | template<typename T> struct W : WBase<T> { typedef int X; int n; }; | ||
void w_test() { | void w_test() { | ||
- W<int>::W w1a; | + W<int>::W w1a; | ||
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}} | |||
W<int>::W::X w1ax; | W<int>::W::X w1ax; | ||
- W<int>::W<int> w1b; | + W<int>::W<int> w1b; | ||
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a template name in this context}} | |||
W<int>::W<int>::X w1bx; | W<int>::W<int>::X w1bx; | ||
- typename W<int>::W w2a; | + typename W<int>::W w2a; | ||
- typename W<int>::W::X w2ax; // expected-error 0-1{{outside of a template}} | + // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}} | ||
- typename W<int>::W<int> w2b; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}} | + // cxx98-error@-2 {{'typename' occurs outside of a template}} | ||
- typename | + typename W<int>::W::X w2ax; | ||
- W<int>::template W<int> w3; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}} | + // cxx98-error@-1 {{'typename' occurs outside of a template}} | ||
- W<int>::template W<int>::X w3x; // expected-error 0-1{{outside of a template}} | + typename W<int>::W<int> w2b; | ||
- typename W<int>::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-2{{outside of a template}} | + // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword}} | ||
- typename W<int>::template W<int>::X w4x; // expected-error 0-2{{outside of a template}} | + // cxx98-error@-2 {{'typename' occurs outside of a template}} | ||
- | + typename W<int>::W<int>::X w2bx; | ||
- TT<W<int>::W> tt1; // expected-error {{qualified reference to 'W' is a constructor name}} | + // cxx98-error@-1 {{'typename' occurs outside of a template}} | ||
- TTy<W<int>::W> tt1a; // expected-error {{qualified reference to 'W' is a constructor name}} | + W<int>::template W<int> w3; | ||
- | + // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} | ||
+ // cxx98-error@-2 {{'template' keyword outside of a template}} | |||
+ W<int>::template W<int>::X w3x; | |||
+ // cxx98-error@-1 {{'template' keyword outside of a template}} | |||
+ typename W<int>::template W<int> w4; | |||
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} | |||
+ // cxx98-error@-2 {{'template' keyword outside of a template}} | |||
+ // cxx98-error@-3 {{'typename' occurs outside of a template}} | |||
+ typename W<int>::template W<int>::X w4x; | |||
+ // cxx98-error@-1 {{'template' keyword outside of a template}} | |||
+ // cxx98-error@-2 {{'typename' occurs outside of a template}} | |||
+ | |||
+ TT<W<int>::W> tt1; | |||
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}} | |||
+ TTy<W<int>::W> tt1a; | |||
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}} | |||
+ TT<W<int>::template W> tt2; | |||
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} | |||
+ // cxx98-error@-2 {{'template' keyword outside of a template}} | |||
TT<W<int>::WBase> tt3; | TT<W<int>::WBase> tt3; | ||
TTy<W<int>::WBase> tt3a; | TTy<W<int>::WBase> tt3a; | ||
- TT<W<int>::template WBase> tt4; | + TT<W<int>::template WBase> tt4; | ||
+ // cxx98-error@-1 {{'template' keyword outside of a template}} | |||
W<int> w; | W<int> w; | ||
(void)w.W::W::n; | (void)w.W::W::n; | ||
(void)w.W<int>::W::n; | (void)w.W<int>::W::n; | ||
(void)w.W<int>::W<int>::n; | (void)w.W<int>::W<int>::n; | ||
- (void)w.W<int>::template W<int>::n; | + (void)w.W<int>::template W<int>::n; | ||
+ // cxx98-error@-1 {{'template' keyword outside of a template}} | |||
} | } | ||
template<typename W> | template<typename W> | ||
void wt_test() { | void wt_test() { | ||
- typename W::W w2a; | + typename W::W w2a; | ||
- typename W::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}} | + // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}} | ||
- TTy<typename W::W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}} | + // cxx98-note@#dr1310-W-int {{in instantiation of function template specialization 'dr1310::wt_test<dr1310::W<int> >' requested here}} | ||
- TT<W::template W> tt3; // expected-error {{qualified reference to 'W' is a constructor name}} | + // since-cxx11-note@#dr1310-W-int {{in instantiation of function template specialization 'dr1310::wt_test<dr1310::W<int>>' requested here}} | ||
+ typename W::template W<int> w4; | |||
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} | |||
+ TTy<typename W::W> tt2; | |||
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}} | |||
+ TT<W::template W> tt3; | |||
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} | |||
} | } | ||
template<typename W> | template<typename W> | ||
void wt_test_good() { | void wt_test_good() { | ||
@@ -111,18 +146,19 @@ namespace dr1310 { // dr1310: 5 | |||
(void)w.template W<int>::W::n; | (void)w.template W<int>::W::n; | ||
(void)w.template W<int>::template W<int>::n; | (void)w.template W<int>::template W<int>::n; | ||
} | } | ||
- template void wt_test<W<int> >(); // | + template void wt_test<W<int> >(); // #dr1310-W-int | ||
template void wt_test_good<W<int> >(); | template void wt_test_good<W<int> >(); | ||
} | } | ||
namespace dr1315 { // dr1315: partial | namespace dr1315 { // dr1315: partial | ||
template <int I, int J> struct A {}; | template <int I, int J> struct A {}; | ||
- template <int I> // expected-note {{non-deducible template parameter 'I'}} | + template <int I> struct A<I + 5, I * 2> {}; | ||
- struct A<I + 5, I * 2> {}; // expected-error {{contains a template parameter that cannot be deduced}} | + // expected-error@-1 {{class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used}} | ||
+ // expected-note@-2 {{non-deducible template parameter 'I'}} | |||
template <int I> struct A<I, I> {}; | template <int I> struct A<I, I> {}; | ||
template <int I, int J, int K> struct B; | template <int I, int J, int K> struct B; | ||
- template <int I, int K> struct B<I, I * 2, K> {}; // | + template <int I, int K> struct B<I, I * 2, K> {}; // #dr1315-B-1 | ||
B<1, 2, 3> b1; | B<1, 2, 3> b1; | ||
// Multiple declarations with the same dependent expression are equivalent | // Multiple declarations with the same dependent expression are equivalent | ||
@@ -131,8 +167,11 @@ namespace dr1315 { // dr1315: partial | |||
B<1, 2, 2>::type b2; | B<1, 2, 2>::type b2; | ||
// Multiple declarations with differing dependent expressions are unordered. | // Multiple declarations with differing dependent expressions are unordered. | ||
- template <int I, int K> struct B<I, I + 1, K> {}; // | + template <int I, int K> struct B<I, I + 1, K> {}; // #dr1315-B-2 | ||
- B<1, 2, 4> b3; | + B<1, 2, 4> b3; | ||
+ // expected-error@-1 {{ambiguous partial specializations of 'B<1, 2, 4>'}} | |||
+ // expected-note@#dr1315-B-1 {{partial specialization matches [with I = 1, K = 4]}} | |||
+ // expected-note@#dr1315-B-2 {{partial specialization matches [with I = 1, K = 4]}} | |||
// FIXME: Under dr1315, this is perhaps valid, but that is not clear: this | // FIXME: Under dr1315, this is perhaps valid, but that is not clear: this | ||
// fails the "more specialized than the primary template" test because the | // fails the "more specialized than the primary template" test because the | ||
@@ -146,7 +185,9 @@ namespace dr1315 { // dr1315: partial | |||
namespace dr1330 { // dr1330: 4 c++11 | namespace dr1330 { // dr1330: 4 c++11 | ||
// exception-specifications are parsed in a context where the class is complete. | // exception-specifications are parsed in a context where the class is complete. | ||
struct A { | struct A { | ||
- void f() throw(T) {} | + void f() throw(T) {} | ||
+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} | |||
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} | |||
struct T {}; | struct T {}; | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
@@ -156,8 +197,12 @@ namespace dr1330 { // dr1330: 4 c++11 | |||
#endif | #endif | ||
}; | }; | ||
- void (A::*af1)() throw(A::T) = &A::f; | + void (A::*af1)() throw(A::T) = &A::f; | ||
- void (A::*af2)() throw() = &A::f; // expected-error-re {{{{not superset|different exception spec}}}} | + // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} | ||
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} | |||
+ void (A::*af2)() throw() = &A::f; | |||
+ // cxx98-14-error@-1 {{target exception specification is not superset of source}} | |||
+ // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (dr1330::A::*)() throw()' with an rvalue of type 'void (dr1330::A::*)() throw(T)': different exception specifications}} | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
static_assert(noexcept(A().g()), ""); | static_assert(noexcept(A().g()), ""); | ||
@@ -166,7 +211,9 @@ namespace dr1330 { // dr1330: 4 c++11 | |||
// Likewise, they're instantiated separately from an enclosing class template. | // Likewise, they're instantiated separately from an enclosing class template. | ||
template<typename U> | template<typename U> | ||
struct B { | struct B { | ||
- void f() throw(T, typename U::type) {} | + void f() throw(T, typename U::type) {} | ||
+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} | |||
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} | |||
struct T {}; | struct T {}; | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
@@ -183,9 +230,6 @@ namespace dr1330 { // dr1330: 4 c++11 | |||
static const int value = true; | static const int value = true; | ||
}; | }; | ||
- void (B<P>::*bpf1)() throw(B<P>::T, int) = &B<P>::f; // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}} | |||
-#if __cplusplus < 201103L | |||
- // expected-error@-2 {{not superset}} | |||
// FIXME: We only delay instantiation in C++11 onwards. In C++98, something | // FIXME: We only delay instantiation in C++11 onwards. In C++98, something | ||
// weird happens: instantiation of B<P> fails because it references T before | // weird happens: instantiation of B<P> fails because it references T before | ||
// it's instantiated, but the diagnostic is suppressed in | // it's instantiated, but the diagnostic is suppressed in | ||
@@ -193,20 +237,20 @@ namespace dr1330 { // dr1330: 4 c++11 | |||
// obviously a bad way to react to this situation; we should still producing | // obviously a bad way to react to this situation; we should still producing | ||
// the "T has not yet been instantiated" error here, rather than giving | // the "T has not yet been instantiated" error here, rather than giving | ||
// confusing errors later on. | // confusing errors later on. | ||
-#endif | + void (B<P>::*bpf1)() throw(B<P>::T, int) = &B<P>::f; | ||
- void (B<P>::*bpf2)() throw(int) = &B<P>::f; // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}} | + // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} | ||
-#if __cplusplus <= 201402L | + // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} | ||
- // expected-error@-2 {{not superset}} | + // cxx98-error@-3 {{target exception specification is not superset of source}} | ||
-#else | + | ||
- // expected-warning@-4 {{not superset}} | + void (B<P>::*bpf2)() throw(int) = &B<P>::f; | ||
-#endif | + // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} | ||
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} | |||
+ // cxx98-14-error@-3 {{target exception specification is not superset of source}} | |||
+ // since-cxx17-warning@-4 {{target exception specification is not superset of source}} | |||
void (B<P>::*bpf3)() = &B<P>::f; | void (B<P>::*bpf3)() = &B<P>::f; | ||
void (B<P>::*bpf4)() throw() = &B<P>::f; | void (B<P>::*bpf4)() throw() = &B<P>::f; | ||
-#if __cplusplus <= 201402L | + // cxx98-14-error@-1 {{target exception specification is not superset of source}} | ||
- // expected-error@-2 {{not superset}} | + // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (B<P>::*)() throw()' with an rvalue of type 'void (dr1330::B<dr1330::P>::*)() throw(T, typename P::type)': different exception specifications}} | ||
-#else | |||
- // expected-error@-4 {{different exception specifications}} | |||
-#endif | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
static_assert(noexcept(B<P>().g()), ""); | static_assert(noexcept(B<P>().g()), ""); | ||
@@ -214,57 +258,64 @@ namespace dr1330 { // dr1330: 4 c++11 | |||
static_assert(!noexcept(B<Q>().g()), ""); | static_assert(!noexcept(B<Q>().g()), ""); | ||
#endif | #endif | ||
- template<typename T> int f() throw(typename T::error) { return 0; } // expected-error 1-4{{prior to '::'}} expected-note 0-1{{prior to '::'}} expected-note 0-1{{requested here}} | + template<typename T> int f() throw(typename T::error) { return 0; } // #dr1330-f | ||
-#if __cplusplus > 201402L | + // expected-error@#dr1330-f {{type 'int' cannot be used prior to '::' because it has no members}} | ||
- // expected-error@-2 0-1{{C++17}} expected-note@-2 0-1{{noexcept}} | + // cxx98-note@#dr1330-f-int {{in instantiation of function template specialization 'dr1330::f<int>' requested here}} | ||
-#endif | + // since-cxx11-note@#dr1330-f-int {{in instantiation of exception specification for 'f<int>' requested here}} | ||
+ // cxx98-14-error@#dr1330-f {{type 'short' cannot be used prior to '::' because it has no members}} | |||
+ // cxx98-14-note@#dr1330-f-short {{in instantiation of function template specialization 'dr1330::f<short>' requested here}} | |||
+ // cxx11-14-note@#dr1330-f {{in instantiation of exception specification for 'f<short>' requested here}} | |||
+ // since-cxx11-error@#dr1330-f {{type 'char' cannot be used prior to '::' because it has no members}} | |||
+ // since-cxx11-note@#dr1330-f-char {{in instantiation of exception specification for 'f<char>' requested here}} | |||
+ // since-cxx11-error@#dr1330-f {{type 'float' cannot be used prior to '::' because it has no members}} | |||
+ // since-cxx11-note@#dr1330-f-float {{in instantiation of exception specification for 'f<float>' requested here}} | |||
+ // since-cxx17-error@#dr1330-f {{ISO C++17 does not allow dynamic exception specifications}} | |||
+ // since-cxx17-note@#dr1330-f {{use 'noexcept(false)' instead}} | |||
+ | |||
// An exception-specification is needed even if the function is only used in | // An exception-specification is needed even if the function is only used in | ||
// an unevaluated operand. | // an unevaluated operand. | ||
- int f1 = sizeof(f<int>()); // | + int f1 = sizeof(f<int>()); // #dr1330-f-int | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- decltype(f<char>()) f2; // | + decltype(f<char>()) f2; // #dr1330-f-char | ||
- bool f3 = noexcept(f<float>()); // | + bool f3 = noexcept(f<float>()); /// #dr1330-f-float | ||
#endif | #endif | ||
// In C++17 onwards, substituting explicit template arguments into the | // In C++17 onwards, substituting explicit template arguments into the | ||
// function type substitutes into the exception specification (because it's | // function type substitutes into the exception specification (because it's | ||
// part of the type). In earlier languages, we don't notice there's a problem | // part of the type). In earlier languages, we don't notice there's a problem | ||
// until we've already started to instantiate. | // until we've already started to instantiate. | ||
- template int f<short>(); | + template int f<short>(); // #dr1330-f-short | ||
-#if __cplusplus >= 201703L | + // since-cxx17-error@-1 {{explicit instantiation of 'f' does not refer to a function template, variable template, member function, member class, or static data member}} | ||
- // expected-error@-2 {{does not refer to a function template}} | + // since-cxx17-note@#dr1330-f {{candidate template ignored: substitution failure [with T = short]: type 'short' cannot be used prior to '::' because it has no members}} | ||
-#else | |||
- // expected-note@-4 {{instantiation of}} | |||
-#endif | |||
template<typename T> struct C { | template<typename T> struct C { | ||
- C() throw(typename T::type); // | + C() throw(typename T::type); // #dr1330-C | ||
-#if __cplusplus > 201402L | + // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} | ||
- // expected-error@-2 0-1{{C++17}} expected-note@-2 0-1{{noexcept}} | + // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} | ||
-#endif | + // cxx98-error@#dr1330-C {{type 'void' cannot be used prior to '::' because it has no members}} | ||
+ // cxx98-note@#dr1330-C-void {{in instantiation of template class 'dr1330::C<void>' requested here}} | |||
+ // expected-error@#dr1330-C {{type 'int' cannot be used prior to '::' because it has no members}} | |||
+ // cxx98-note@#dr1330-C-int {{in instantiation of template class 'dr1330::C<int>' requested here}} | |||
+ // since-cxx11-note@#dr1330-C-int {{in instantiation of exception specification for 'C' requested here}} | |||
+ // since-cxx11-note@#dr1330-e {{in evaluation of exception specification for 'dr1330::E::E' needed here}} | |||
}; | }; | ||
- struct D : C<void> {}; // | + struct D : C<void> {}; // #dr1330-C-void | ||
-#if __cplusplus < 201103L | |||
- // expected-note@-2 {{instantiation of}} | |||
-#endif | |||
void f(D &d) { d = d; } // ok | void f(D &d) { d = d; } // ok | ||
- struct E : C<int> {}; // | + struct E : C<int> {}; // #dr1330-C-int | ||
-#if __cplusplus >= 201103L | + E e; // #dr1330-e | ||
- E e; // expected-note {{needed here}} | |||
-#endif | |||
} | } | ||
namespace dr1341 { // dr1341: sup P0683R1 | namespace dr1341 { // dr1341: sup P0683R1 | ||
#if __cplusplus >= 202002L | #if __cplusplus >= 202002L | ||
int a; | int a; | ||
-const int b = 0; // #dr1341-b | +const int b = 0; // #dr1341-b | ||
struct S { | struct S { | ||
int x1 : 8 = 42; | int x1 : 8 = 42; | ||
int x2 : 8 { 42 }; | int x2 : 8 { 42 }; | ||
int y1 : true ? 8 : a = 42; | int y1 : true ? 8 : a = 42; | ||
int y2 : true ? 8 : b = 42; | int y2 : true ? 8 : b = 42; | ||
- // | + // since-cxx20-error@-1 {{cannot assign to variable 'b' with const-qualified type 'const int'}} | ||
- // | + // since-cxx20-note@#dr1341-b {{variable 'b' declared const here}} | ||
int y3 : (true ? 8 : b) = 42; | int y3 : (true ? 8 : b) = 42; | ||
int z : 1 || new int { 0 }; | int z : 1 || new int { 0 }; | ||
}; | }; | ||
@@ -272,44 +323,66 @@ struct S { | |||
} | } | ||
namespace dr1346 { // dr1346: 3.5 | namespace dr1346 { // dr1346: 3.5 | ||
- auto a(1); | + auto a(1); | ||
- auto b(1, 2); // expected-error {{multiple expressions}} expected-error 0-1{{extension}} | + // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}} | ||
+ auto b(1, 2); | |||
+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}} | |||
+ // expected-error@-2 {{initializer for variable 'b' with type 'auto' contains multiple expressions}} | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- auto c({}); | + auto c({}); | ||
- auto d({1}); // expected-error {{parenthesized initializer list}} | + // since-cxx11-error@-1 {{cannot deduce type for variable 'c' with type 'auto' from parenthesized initializer list}} | ||
- auto e({1, 2}); // expected-error {{parenthesized initializer list}} | + auto d({1}); | ||
+ // since-cxx11-error@-1 {{cannot deduce type for variable 'd' with type 'auto' from parenthesized initializer list}} | |||
+ auto e({1, 2}); | |||
+ // since-cxx11-error@-1 {{cannot deduce type for variable 'e' with type 'auto' from parenthesized initializer list}} | |||
#endif | #endif | ||
- template<typename...Ts> void f(Ts ...ts) { | + template<typename...Ts> void f(Ts ...ts) { | ||
- auto x(ts...); // expected-error {{empty}} expected-error 0-1{{extension}} | + // cxx98-error@-1 {{variadic templates are a C++11 extension}} | ||
+ auto x(ts...); | |||
+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}} | |||
+ // expected-error@-2 {{initializer for variable 'x' with type 'auto' is empty}} | |||
+ // expected-note@#dr1346-f {{in instantiation of function template specialization 'dr1346::f<>' requested here}} | |||
} | } | ||
- template void f(); // | + template void f(); // #dr1346-f | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
void init_capture() { | void init_capture() { | ||
- [a(1)] {} (); | + [a(1)] {} (); | ||
- [b(1, 2)] {} (); // expected-error {{multiple expressions}} expected-error 0-1{{extension}} | + // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} | ||
-#if __cplusplus >= 201103L | + [b(1, 2)] {} (); | ||
- [c({})] {} (); // expected-error {{parenthesized initializer list}} expected-error 0-1{{extension}} | + // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} | ||
- [d({1})] {} (); // expected-error {{parenthesized initializer list}} expected-error 0-1{{extension}} | + // since-cxx11-error@-2 {{initializer for lambda capture 'b' contains multiple expressions}} | ||
- [e({1, 2})] {} (); // expected-error {{parenthesized initializer list}} expected-error 0-1{{extension}} | + [c({})] {} (); | ||
-#endif | + // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} | ||
+ // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'c' from parenthesized initializer list}} | |||
+ [d({1})] {} (); | |||
+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} | |||
+ // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'd' from parenthesized initializer list}} | |||
+ [e({1, 2})] {} (); | |||
+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} | |||
+ // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'e' from parenthesized initializer list}} | |||
} | } | ||
#endif | #endif | ||
} | } | ||
-namespace dr1347 { // dr1347: | +namespace dr1347 { // dr1347: 3.1 | ||
- auto x = 5, *y = &x; | + auto x = 5, *y = &x; | ||
- auto z = y, *q = y; // expected-error {{'auto' deduced as 'int *' in declaration of 'z' and deduced as 'int' in declaration of 'q'}} expected-error 0-1{{extension}} | + // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}} | ||
+ auto z = y, *q = y; | |||
+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}} | |||
+ // expected-error@-2 {{'auto' deduced as 'int *' in declaration of 'z' and deduced as 'int' in declaration of 'q'}} | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- auto a = 5, b = {1, 2}; | + auto a = 5, b = {1, 2}; | ||
- auto (*fp)(int) -> int, i = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}} | + // since-cxx11-error@-1 {{'auto' deduced as 'int' in declaration of 'a' and deduced as 'std::initializer_list | ||
+ auto (*fp)(int) -> int, i = 0; | |||
+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}} | |||
#endif | #endif | ||
} | } | ||
-namespace dr1358 { // dr1358: | +namespace dr1358 { // dr1358: 3.1 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
struct Lit { constexpr operator int() const { return 0; } }; | struct Lit { constexpr operator int() const { return 0; } }; | ||
- struct NonLit { NonLit(); operator int(); }; // | + struct NonLit { NonLit(); operator int(); }; // #dr1358-NonLit | ||
struct NonConstexprConv | struct NonConstexprConv | ||
struct Virt { virtual int f(int) const; }; | struct Virt { virtual int f(int) const; }; | ||
@@ -336,8 +409,12 @@ namespace dr1358 { // dr1358: yes | |||
// But the corresponding non-template cases are rejected. | // But the corresponding non-template cases are rejected. | ||
struct B : Virt { | struct B : Virt { | ||
int member; | int member; | ||
- constexpr B(NonLit u) : member(u) {} | + constexpr B(NonLit u) : member(u) {} | ||
- constexpr NonLit f(NonLit u) const { return NonLit(); } // expected-error {{not a literal type}} | + // since-cxx11-error@-1 {{constexpr constructor's 1st parameter type 'NonLit' is not a literal type}} | ||
+ // since-cxx11-note@#dr1358-NonLit {{'NonLit' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} | |||
+ constexpr NonLit f(NonLit u) const { return NonLit(); } | |||
+ // since-cxx11-error@-1 {{constexpr function's return type 'NonLit' is not a literal type}} | |||
+ // since-cxx11-note@#dr1358-NonLit {{'NonLit' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} | |||
}; | }; | ||
#endif | #endif | ||
} | } | ||
@@ -345,65 +422,113 @@ namespace dr1358 { // dr1358: yes | |||
namespace dr1359 { // dr1359: 3.5 | namespace dr1359 { // dr1359: 3.5 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
union A { constexpr A() = default; }; | union A { constexpr A() = default; }; | ||
- union B { constexpr B() = default; int a; }; // | + union B { constexpr B() = default; int a; }; // #dr1359-B | ||
- union C { constexpr C() = default; int a, b; }; // expected-error {{not constexpr}} expected-note 2{{candidate}} | + // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}} | ||
- struct X { constexpr X() = default; union {}; }; // expected-error {{does not declare anything}} | + union C { constexpr C() = default; int a, b; }; // #dr1359-C | ||
- struct Y { constexpr Y() = default; union { int a; }; }; // expected-error {{not constexpr}} expected-note 2{{candidate}} | + // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}} | ||
+ struct X { constexpr X() = default; union {}; }; | |||
+ // since-cxx11-error@-1 {{declaration does not declare anything}} | |||
+ struct Y { constexpr Y() = default; union { int a; }; }; // #dr1359-Y | |||
+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}} | |||
constexpr A a = A(); | constexpr A a = A(); | ||
- constexpr B b = B(); | + constexpr B b = B(); | ||
- constexpr C c = C(); // expected-error {{no matching}} | + // cxx11-17-error@-1 {{no matching constructor for initialization of 'B'}} | ||
+ // cxx11-17-note@#dr1359-B {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} | |||
+ // cxx11-17-note@#dr1359-B {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} | |||
+ constexpr C c = C(); | |||
+ // cxx11-17-error@-1 {{no matching constructor for initialization of 'C'}} | |||
+ // cxx11-17-note@#dr1359-C {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} | |||
+ // cxx11-17-note@#dr1359-C {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} | |||
constexpr X x = X(); | constexpr X x = X(); | ||
- constexpr Y y = Y(); | + constexpr Y y = Y(); | ||
+ // cxx11-17-error@-1 {{no matching constructor for initialization of 'Y'}} | |||
+ // cxx11-17-note@#dr1359-Y {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} | |||
+ // cxx11-17-note@#dr1359-Y {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} | |||
#endif | #endif | ||
} | } | ||
namespace dr1388 { // dr1388: 4 | namespace dr1388 { // dr1388: 4 | ||
- template<typename A, typename ...T> void f(T..., A); // | + template<typename A, typename ...T> void f(T..., A); // #dr1388-f | ||
- template<typename ...T> void g(T..., int); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}} | + // cxx98-error@-1 {{variadic templates are a C++11 extension}} | ||
- template<typename ...T, typename A> void h(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}} | + template<typename ...T> void g(T..., int); // #dr1388-g | ||
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}} | |||
+ template<typename ...T, typename A> void h(T..., A); // #dr1388-h | |||
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}} | |||
void test_f() { | void test_f() { | ||
f(0); // ok, trailing parameter pack deduced to empty | f(0); // ok, trailing parameter pack deduced to empty | ||
- f(0, 0); | + f(0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'f'}} | |||
+ // expected-note@#dr1388-f {{candidate function [with A = int, T = <>] not viable: requires 1 argument, but 2 were provided}} | |||
f<int>(0); | f<int>(0); | ||
- f<int>(0, 0); | + f<int>(0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'f'}} | |||
+ // expected-note@#dr1388-f {{candidate function [with A = int, T = <>] not viable: requires 1 argument, but 2 were provided}} | |||
f<int, int>(0, 0); | f<int, int>(0, 0); | ||
- f<int, int, int>(0, 0); | + f<int, int, int>(0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'f'}} | |||
+ // expected-note@#dr1388-f {{candidate function [with A = int, T = <int, int>] not viable: requires 3 arguments, but 2 were provided}} | |||
g(0); | g(0); | ||
- g(0, 0); | + g(0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'g'}} | |||
+ // expected-note@#dr1388-g {{candidate function [with T = <>] not viable: requires 1 argument, but 2 were provided}} | |||
g<>(0); | g<>(0); | ||
- g<int>(0); | + g<int>(0); | ||
+ // expected-error@-1 {{no matching function for call to 'g'}} | |||
+ // expected-note@#dr1388-g {{candidate function [with T = <int>] not viable: requires 2 arguments, but 1 was provided}} | |||
g<int>(0, 0); | g<int>(0, 0); | ||
h(0); | h(0); | ||
- h(0, 0); | + h(0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'h'}} | |||
+ // expected-note@#dr1388-h {{candidate function [with T = <>, A = int] not viable: requires 1 argument, but 2 were provided}} | |||
h<int>(0, 0); | h<int>(0, 0); | ||
- h<int, int>(0, 0); | + h<int, int>(0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'h'}} | |||
+ // expected-note@#dr1388-h {{candidate template ignored: couldn't infer template argument 'A'}} | |||
} | } | ||
// A non-trailing parameter pack is still a non-deduced context, even though | // A non-trailing parameter pack is still a non-deduced context, even though | ||
// we know exactly how many arguments correspond to it. | // we know exactly how many arguments correspond to it. | ||
template<typename T, typename U> struct pair {}; | template<typename T, typename U> struct pair {}; | ||
- template<typename ...T> struct tuple { typedef char type; }; // | + template<typename ...T> struct tuple { typedef char type; }; // | ||
- template<typename ...T, typename ...U> void f_pair_1(pair<T, U>..., int); // expected-error 0-2{{C++11}} expected-note {{[with T = <int, long>]: deduced incomplete pack <(no value), (no value)> for template parameter 'U'}} | + // cxx98-error@-1 {{variadic templates are a C++11 extension}} | ||
- template<typename ...T, typename U> void | + template<typename ...T, typename ...U> void f_pair_1(pair<T, U>..., int); // #dr1388-f-1 | ||
- template<typename ...T, typename ...U> void f_pair_3(pair<T, U>..., tuple<U...>); // expected-error 0-2{{C++11}} expected-note {{deduced packs of different lengths for parameter 'U' (<(no value), (no value)> vs. <char>)}} | + // cxx98-error@-1 {{variadic templates are a C++11 extension}} | ||
- template<typename ...T> void f_pair_4(pair<T, char>..., T...); // expected-error 0-2{{C++11}} expected-note {{<int, long> vs. <int, long, const char *>}} | + // cxx98-error@-2 {{variadic templates are a C++11 extension}} | ||
+ template<typename ...T, typename U> void f_pair_2(pair<T, char>..., U); | |||
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}} | |||
+ template<typename ...T, typename ...U> void f_pair_3(pair<T, U>..., tuple<U...>); // #dr1388-f-3 | |||
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}} | |||
+ // cxx98-error@-2 {{variadic templates are a C++11 extension}} | |||
+ template<typename ...T> void f_pair_4(pair<T, char>..., T...); // #dr1388-f-4 | |||
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}} | |||
void g(pair<int, char> a, pair<long, char> b, tuple<char, char> c) { | void g(pair<int, char> a, pair<long, char> b, tuple<char, char> c) { | ||
- f_pair_1<int, long>(a, b, 0); | + f_pair_1<int, long>(a, b, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'f_pair_1'}} | |||
+ // expected-note@#dr1388-f-1 {{candidate template ignored: substitution failure [with T = <int, long>]: deduced incomplete pack <(no value), (no value)> for template parameter 'U'}} | |||
f_pair_2<int, long>(a, b, 0); | f_pair_2<int, long>(a, b, 0); | ||
f_pair_3<int, long>(a, b, c); | f_pair_3<int, long>(a, b, c); | ||
- f_pair_3<int, long>(a, b, tuple<char>()); | + f_pair_3<int, long>(a, b, tuple<char>()); | ||
+ // expected-error@-1 {{no matching function for call to 'f_pair_3'}} | |||
+ // expected-note@#dr1388-f-3 {{candidate template ignored: deduced packs of different lengths for parameter 'U' (<(no value), (no value)> vs. <char>)}} | |||
f_pair_4<int, long>(a, b, 0, 0L); | f_pair_4<int, long>(a, b, 0, 0L); | ||
- f_pair_4<int, long>(a, b, 0, 0L, "foo"); | + f_pair_4<int, long>(a, b, 0, 0L, "foo"); | ||
+ // expected-error@-1 {{no matching function for call to 'f_pair_4'}} | |||
+ // expected-note@#dr1388-f-4 {{candidate template ignored: deduced packs of different lengths for parameter 'T' (<int, long> vs. <int, long, const char *>)}} | |||
} | } | ||
} | } | ||
namespace dr1391 { // dr1391: partial | namespace dr1391 { // dr1391: partial | ||
struct A {}; struct B : A {}; | struct A {}; struct B : A {}; | ||
- template<typename T> struct C { C(int); typename T::error error; }; // | + template<typename T> struct C { C(int); typename T::error error; }; // #dr1391-C | ||
+ // expected-error@#dr1391-C {{type 'int' cannot be used prior to '::' because it has no members}} | |||
+ // expected-note@#dr1391-b {{in instantiation of template class 'dr1391::C<int>' requested here}} | |||
+ // expected-note@#dr1391-b {{while substituting deduced template arguments into function template 'b' [with T = int]}} | |||
+ // expected-error@#dr1391-C {{type 'double' cannot be used prior to '::' because it has no members}} | |||
+ // expected-note@#dr1391-c {{in instantiation of template class 'dr1391::C<double>' requested here}} | |||
template<typename T> struct D {}; | template<typename T> struct D {}; | ||
// No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match. | // No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match. | ||
@@ -444,28 +569,36 @@ namespace dr1391 { // dr1391: partial | |||
void test_b() { | void test_b() { | ||
b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int> | b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int> | ||
// FIXME: The "while substituting" note should point at the overload candidate. | // FIXME: The "while substituting" note should point at the overload candidate. | ||
- b<int>(0, 0); // expected-note {{instantiation of}} expected-note {{while substituting}} | + b<int>(0, 0); // #dr1391-b | ||
} | } | ||
template<typename T> struct Id { typedef T type; }; | template<typename T> struct Id { typedef T type; }; | ||
template<typename T> void c(T, typename Id<C<T> >::type); | template<typename T> void c(T, typename Id<C<T> >::type); | ||
void test_c() { | void test_c() { | ||
// Implicit conversion sequences for dependent types are checked later. | // Implicit conversion sequences for dependent types are checked later. | ||
- c(0.0, 0); // expected-note {{instantiation of}} | + c(0.0, 0); // #dr1391-c | ||
} | } | ||
namespace partial_ordering | namespace partial_ordering | ||
// FIXME: Second template should be considered more specialized because non-dependent parameter is ignored. | // FIXME: Second template should be considered more specialized because non-dependent parameter is ignored. | ||
- template<typename T> int a(T, short) = delete; // | + template<typename T> int a(T, short) = delete; // #dr1391-a-short | ||
- template<typename T> int a(T*, char); // expected-note {{candidate}} | + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} | ||
- int test_a = a((int*)0, 0); // FIXME: expected-error {{ambiguous}} | + template<typename T> int a(T*, char); // #dr1391-a-char | ||
+ int test_a = a((int*)0, 0); | |||
+ // expected-error@-1 {{call to 'a' is ambiguous}} FIXME | |||
+ // expected-note@#dr1391-a-short {{candidate function [with T = int *] has been explicitly deleted}} | |||
+ // expected-note@#dr1391-a-char {{candidate function [with T = int]}} | |||
// FIXME: Second template should be considered more specialized: | // FIXME: Second template should be considered more specialized: | ||
// deducing #1 from #2 ignores the second P/A pair, so deduction succeeds, | // deducing #1 from #2 ignores the second P/A pair, so deduction succeeds, | ||
// deducing #2 from #1 fails to deduce T, so deduction fails. | // deducing #2 from #1 fails to deduce T, so deduction fails. | ||
- template<typename T> int b(T, int) = delete; // | + template<typename T> int b(T, int) = delete; // #dr1391-b-int | ||
- template<typename T, typename U> int b(T*, U); // expected-note {{candidate}} | + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} | ||
- int test_b = b((int*)0, 0); // FIXME: expected-error {{ambiguous}} | + template<typename T, typename U> int b(T*, U); // #dr1391-b-U | ||
+ int test_b = b((int*)0, 0); | |||
+ // expected-error@-1 {{call to 'b' is ambiguous}} FIXME | |||
+ // expected-note@#dr1391-b-int {{candidate function [with T = int *] has been explicitly deleted}} | |||
+ // expected-note@#dr1391-b-U {{candidate function [with T = int, U = int]}} | |||
// Unintended consequences: because partial ordering does not consider | // Unintended consequences: because partial ordering does not consider | ||
// explicit template arguments, and deduction from a non-dependent type | // explicit template arguments, and deduction from a non-dependent type | ||
@@ -499,26 +632,26 @@ namespace dr1395 { // dr1395: 16 | |||
namespace dr1397 { // dr1397: 3.2 | namespace dr1397 { // dr1397: 3.2 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
-struct A { | +struct A { | ||
- void *p = A{}; // #dr1397-void-p | +// cxx11-error@-1 {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}} | ||
-#if __cplusplus == 201103L | +// cxx11-note@#dr1397-p {{in evaluation of exception specification for 'dr1397::A::A' needed here}} | ||
- // expected-error@#dr1397-struct-A {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}} | +// cxx11-note@#dr1397-p {{default member initializer declared here}} | ||
- // expected-note@#dr1397-void-p {{in evaluation of exception specification for 'dr1397::A::A' needed here}} | + void *p = A{}; // #dr1397-p | ||
- // expected-note@#dr1397-void-p {{default member initializer declared here}} | + // since-cxx14-error@-1 {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}} | ||
-#elif __cplusplus >= 201402L | + // since-cxx14-note@-2 {{default member initializer declared here}} | ||
- // expected-error@#dr1397-void-p {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}} | |||
- // expected-note@#dr1397-void-p {{default member initializer declared here}} | |||
-#endif | |||
operator void*() const { return nullptr; } | operator void*() const { return nullptr; } | ||
}; | }; | ||
#endif | #endif | ||
} // namespace dr1397 | } // namespace dr1397 | ||
namespace dr1399 { // dr1399: dup 1388 | namespace dr1399 { // dr1399: dup 1388 | ||
- template<typename ...T> void f(T..., int, T...) {} // | + template<typename ...T> void f(T..., int, T...) {} // #dr1399-f | ||
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}} | |||
void g() { | void g() { | ||
f(0); | f(0); | ||
f<int>(0, 0, 0); | f<int>(0, 0, 0); | ||
- f(0, 0, 0); | + f(0, 0, 0); | ||
+ // expected-error@-1 {{no matching function for call to 'f'}} | |||
+ // expected-note@#dr1399-f {{candidate template ignored: deduced packs of different lengths for parameter 'T' (<> vs. <int, int>)}} | |||
} | } | ||
} | } |
@@ -1,8 +1,10 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,since-cxx11, -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx14-17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx14-17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++ | +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors | ||
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors | |||
namespace dr1413 { // dr1413: 12 | namespace dr1413 { // dr1413: 12 | ||
template<int> struct Check { | template<int> struct Check { | ||
@@ -15,24 +17,41 @@ namespace dr1413 { // dr1413: 12 | |||
void d(); | void d(); | ||
void f() { | void f() { | ||
- Check<true ? 0 : A::unknown_spec>::type *var1; | + Check<true ? 0 : A::unknown_spec>::type *var1; | ||
- Check<true ? 0 : a>::type *var2; // ok, variable declaration expected-note 0+{{here}} | + // expected-error@-1 {{use of undeclared identifier 'var1'}} | ||
- Check<true ? 0 : b>::type *var3; // expected-error {{undeclared identifier 'var3'}} | + | ||
- Check<true ? 0 : ((void)c, 0)>::type *var4; // expected-error {{undeclared identifier 'var4'}} | + // ok, variable declaration | ||
+ Check<true ? 0 : a>::type *var2; // #dr1413-var2 | |||
+ Check<true ? 0 : b>::type *var3; | |||
+ // expected-error@-1 {{use of undeclared identifier 'var3'}} | |||
+ // expected-note@#dr1413-var2 {{'var2' declared here}} | |||
+ Check<true ? 0 : ((void)c, 0)>::type *var4; | |||
+ // expected-error@-1 {{use of undeclared identifier 'var4'}} | |||
+ // expected-note@#dr1413-var2 {{'var2' declared here}} | |||
+ | |||
// value-dependent because of the implied type-dependent 'this->', not because of 'd' | // value-dependent because of the implied type-dependent 'this->', not because of 'd' | ||
- Check<true ? 0 : (d(), 0)>::type *var5; | + Check<true ? 0 : (d(), 0)>::type *var5; | ||
+ // expected-error@-1 {{use of undeclared identifier 'var5'}} | |||
+ // expected-note@#dr1413-var2 {{'var2' declared here}} | |||
+ | |||
// value-dependent because of the value-dependent '&' operator, not because of 'A::d' | // value-dependent because of the value-dependent '&' operator, not because of 'A::d' | ||
- Check<true ? 0 : (&A::d(), 0)>::type *var5; | + Check<true ? 0 : (&A::d(), 0)>::type *var5; | ||
+ // expected-error@-1 {{use of undeclared identifier 'var5'}} | |||
+ // expected-note@#dr1413-var2 {{'var2' declared here}} | |||
} | } | ||
}; | }; | ||
} | } | ||
namespace dr1423 { // dr1423: 11 | namespace dr1423 { // dr1423: 11 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- bool b1 = nullptr; | + bool b1 = nullptr; | ||
- bool b2(nullptr); // expected-warning {{implicit conversion of nullptr constant to 'bool'}} | + // since-cxx11-error@-1 {{cannot initialize a variable of type 'bool' with an rvalue of type 'std::nullptr_t'}} | ||
- bool b3 = {nullptr}; // expected-error {{cannot initialize}} | + bool b2(nullptr); | ||
- | + // since-cxx11-warning@-1 {{implicit conversion of nullptr constant to 'bool'}} | ||
+ bool b3 = {nullptr}; | |||
+ // since-cxx11-error@-1 {{cannot initialize a variable of type 'bool' with an rvalue of type 'std::nullptr_t'}} | |||
+ bool b4{nullptr}; | |||
+ // since-cxx11-warning@-1 {{implicit conversion of nullptr constant to 'bool'}} | |||
#endif | #endif | ||
} | } | ||
@@ -62,7 +81,8 @@ namespace dr1432 { // dr1432: 16 | |||
namespace dr1443 { // dr1443: yes | namespace dr1443 { // dr1443: yes | ||
struct A { | struct A { | ||
int i; | int i; | ||
- A() { void foo(int=i); } | + A() { void foo(int=i); } | ||
+ // expected-error@-1 {{default argument references 'this'}} | |||
}; | }; | ||
} | } | ||
@@ -70,49 +90,54 @@ namespace dr1460 { // dr1460: 3.5 | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
namespace DRExample { | namespace DRExample { | ||
union A { | union A { | ||
- union {}; | + union {}; | ||
- | + // expected-error@-1 {{declaration does not declare anything}} | ||
+ union {}; | |||
+ // expected-error@-1 {{declaration does not declare anything}} | |||
constexpr A() {} | constexpr A() {} | ||
}; | }; | ||
constexpr A a = A(); | constexpr A a = A(); | ||
union B { | union B { | ||
- union {}; | + union {}; | ||
- | + // expected-error@-1 {{declaration does not declare anything}} | ||
+ union {}; | |||
+ // expected-error@-1 {{declaration does not declare anything}} | |||
constexpr B() = default; | constexpr B() = default; | ||
}; | }; | ||
constexpr B b = B(); | constexpr B b = B(); | ||
union C { | union C { | ||
- union {}; | + union {}; | ||
- | + // expected-error@-1 {{declaration does not declare anything}} | ||
+ union {}; | |||
+ // expected-error@-1 {{declaration does not declare anything}} | |||
}; | }; | ||
constexpr C c = C(); | constexpr C c = C(); | ||
-#if __cplusplus | +#if __cplusplus >= 201403L | ||
constexpr void f() { C c; } | constexpr void f() { C c; } | ||
static_assert((f(), true), ""); | static_assert((f(), true), ""); | ||
#endif | #endif | ||
} | } | ||
union A {}; | union A {}; | ||
- union B { int n; }; // | + union B { int n; }; // #dr1460-B | ||
union C { int n = 0; }; | union C { int n = 0; }; | ||
- struct D { union {}; }; | + struct D { union {}; }; | ||
- struct E { union { int n; }; }; // expected-note 0+{{here}} | + // expected-error@-1 {{declaration does not declare anything}} | ||
+ struct E { union { int n; }; }; // #dr1460-E | |||
struct F { union { int n = 0; }; }; | struct F { union { int n = 0; }; }; | ||
struct X { | struct X { | ||
friend constexpr A::A() noexcept; | friend constexpr A::A() noexcept; | ||
friend constexpr B::B() noexcept; | friend constexpr B::B() noexcept; | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{constexpr declaration of 'B' follows non-constexpr declaration}} | ||
- // expected-error@-2 {{follows non-constexpr declaration}} | + // cxx11-17-note@#dr1460-B {{previous declaration is here}} | ||
-#endif | |||
friend constexpr C::C() noexcept; | friend constexpr C::C() noexcept; | ||
friend constexpr D::D() noexcept; | friend constexpr D::D() noexcept; | ||
friend constexpr E::E() noexcept; | friend constexpr E::E() noexcept; | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{constexpr declaration of 'E' follows non-constexpr declaration}} | ||
- // expected-error@-2 {{follows non-constexpr declaration}} | + // cxx11-17-note@#dr1460-E {{previous declaration is here}} | ||
-#endif | |||
friend constexpr F::F() noexcept; | friend constexpr F::F() noexcept; | ||
}; | }; | ||
@@ -128,79 +153,77 @@ namespace dr1460 { // dr1460: 3.5 | |||
namespace Defaulted { | namespace Defaulted { | ||
union A { constexpr A() = default; }; | union A { constexpr A() = default; }; | ||
union B { int n; constexpr B() = default; }; | union B { int n; constexpr B() = default; }; | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}} | ||
- // expected-error@-2 {{not constexpr}} | |||
-#endif | |||
union C { int n = 0; constexpr C() = default; }; | union C { int n = 0; constexpr C() = default; }; | ||
- struct D { union {}; constexpr D() = default; }; | + struct D { union {}; constexpr D() = default; }; | ||
+ // expected-error@-1 {{declaration does not declare anything}} | |||
struct E { union { int n; }; constexpr E() = default; }; | struct E { union { int n; }; constexpr E() = default; }; | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}} | ||
- // expected-error@-2 {{not constexpr}} | |||
-#endif | |||
struct F { union { int n = 0; }; constexpr F() = default; }; | struct F { union { int n = 0; }; constexpr F() = default; }; | ||
struct G { union { int n = 0; }; union { int m; }; constexpr G() = default; }; | struct G { union { int n = 0; }; union { int m; }; constexpr G() = default; }; | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}} | ||
- // expected-error@-2 {{not constexpr}} | |||
-#endif | |||
struct H { | struct H { | ||
union { | union { | ||
int n = 0; | int n = 0; | ||
}; | }; | ||
- union { // expected-note 0-2{{member not initialized}} | + union { // #dr1460-H-union | ||
int m; | int m; | ||
}; | }; | ||
constexpr H() {} | constexpr H() {} | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{constexpr constructor that does not initialize all members is a C++20 extension}} | ||
- // expected-error@-2 {{initialize all members}} | + // cxx11-17-note@#dr1460-H-union {{member not initialized by constructor}} | ||
-#endif | |||
constexpr H(bool) : m(1) {} | constexpr H(bool) : m(1) {} | ||
constexpr H(char) : n(1) {} | constexpr H(char) : n(1) {} | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{constexpr constructor that does not initialize all members is a C++20 extension}} | ||
- // expected-error@-2 {{initialize all members}} | + // cxx11-17-note@#dr1460-H-union {{member not initialized by constructor}} | ||
-#endif | |||
constexpr H(double) : m(1), n(1) {} | constexpr H(double) : m(1), n(1) {} | ||
}; | }; | ||
} | } | ||
-#if __cplusplus | +#if __cplusplus >= 201403L | ||
template<typename T> constexpr bool check() { | template<typename T> constexpr bool check() { | ||
- T t; | + T t; // #dr1460-t | ||
-#if __cplusplus <= 201703L | |||
- // expected-note-re@-2 2{{non-constexpr constructor '{{[BE]}}'}} | |||
-#endif | |||
return true; | return true; | ||
} | } | ||
static_assert(check<A>(), ""); | static_assert(check<A>(), ""); | ||
- static_assert(check<B>(), ""); | + static_assert(check<B>(), ""); // #dr1460-check-B | ||
-#if __cplusplus <= 201703L | + // cxx14-17-error@-1 {{static assertion expression is not an integral constant expression}} | ||
- // expected-error@-2 {{constant}} expected-note@-2 {{in call}} | + // cxx14-17-note@#dr1460-t {{non-constexpr constructor 'B' cannot be used in a constant expression}} | ||
-#endif | + // cxx14-17-note@#dr1460-check-B {{in call to 'check<dr1460::B>()'}} | ||
+ // cxx14-17-note@#dr1460-B {{declared here}} | |||
static_assert(check<C>(), ""); | static_assert(check<C>(), ""); | ||
static_assert(check<D>(), ""); | static_assert(check<D>(), ""); | ||
- static_assert(check<E>(), ""); | + static_assert(check<E>(), ""); // #dr1460-check-E | ||
-#if __cplusplus <= 201703L | + // cxx14-17-error@-1 {{static assertion expression is not an integral constant expression}} | ||
- // expected-error@-2 {{constant}} expected-note@-2 {{in call}} | + // cxx14-17-note@#dr1460-t {{non-constexpr constructor 'E' cannot be used in a constant expression}} | ||
-#endif | + // cxx14-17-note@#dr1460-check-E {{in call to 'check<dr1460::E>()'}} | ||
+ // cxx14-17-note@#dr1460-E {{declared here}} | |||
static_assert(check<F>(), ""); | static_assert(check<F>(), ""); | ||
#endif | #endif | ||
union G { | union G { | ||
- int a = 0; // expected-note {{previous initialization is here}} | + int a = 0; // #dr1460-G-a | ||
- int b = 0; | + int b = 0; | ||
+ // expected-error@-1 {{initializing multiple members of union}} | |||
+ // expected-note@#dr1460-G-a {{previous initialization is here}} | |||
}; | }; | ||
union H { | union H { | ||
union { | union { | ||
- int a = 0; // expected-note {{previous initialization is here}} | + int a = 0; // #dr1460-H-a | ||
}; | }; | ||
union { | union { | ||
- int b = 0; | + int b = 0; | ||
+ // expected-error@-1 {{initializing multiple members of union}} | |||
+ // expected-note@#dr1460-H-a {{previous initialization is here}} | |||
}; | }; | ||
}; | }; | ||
struct I { | struct I { | ||
union { | union { | ||
- int a = 0; // expected-note {{previous initialization is here}} | + int a = 0; // #dr1460-I-a | ||
- int b = 0; | + int b = 0; | ||
+ // expected-error@-1 {{initializing multiple members of union}} | |||
+ // expected-note@#dr1460-I-a {{previous initialization is here}} | |||
}; | }; | ||
}; | }; | ||
struct J { | struct J { | ||
@@ -223,14 +246,24 @@ namespace dr1460 { // dr1460: 3.5 | |||
constexpr B(const char*) {} | constexpr B(const char*) {} | ||
}; | }; | ||
static_assert(B().a == 1, ""); | static_assert(B().a == 1, ""); | ||
- static_assert(B().b == 2, ""); | + static_assert(B().b == 2, ""); | ||
- static_assert(B('x').a == 0, ""); // expected-error {{constant}} expected-note {{read of}} | + // expected-error@-1 {{static assertion expression is not an integral constant expression}} | ||
+ // expected-note@-2 {{read of member 'b' of union with active member 'a' is not allowed in a constant expression}} | |||
+ static_assert(B('x').a == 0, ""); | |||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'a' of union with active member 'b' is not allowed in a constant expression}} | |||
static_assert(B('x').b == 4, ""); | static_assert(B('x').b == 4, ""); | ||
- static_assert(B(123).b == 2, ""); | + static_assert(B(123).b == 2, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'b' of union with active member 'c' is not allowed in a constant expression}} | |||
static_assert(B(123).c == 3, ""); | static_assert(B(123).c == 3, ""); | ||
- static_assert(B("").a == 1, ""); | + static_assert(B("").a == 1, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'a' of union with active member 'b' is not allowed in a constant expression}} | |||
static_assert(B("").b == 2, ""); | static_assert(B("").b == 2, ""); | ||
- static_assert(B("").c == 3, ""); | + static_assert(B("").c == 3, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}} | |||
struct C { | struct C { | ||
union { int a, b = 2, c; }; | union { int a, b = 2, c; }; | ||
@@ -243,31 +276,55 @@ namespace dr1460 { // dr1460: 3.5 | |||
}; | }; | ||
static_assert(C().a == 1, ""); | static_assert(C().a == 1, ""); | ||
- static_assert(C().b == 2, ""); | + static_assert(C().b == 2, ""); | ||
- static_assert(C().d == 4, ""); // expected-error {{constant}} expected-note {{read of}} | + // expected-error@-1 {{static assertion expression is not an integral constant expression}} | ||
+ // expected-note@-2 {{read of member 'b' of union with active member 'a' is not allowed in a constant expression}} | |||
+ static_assert(C().d == 4, ""); | |||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'd' of union with active member 'e' is not allowed in a constant expression}} | |||
static_assert(C().e == 5, ""); | static_assert(C().e == 5, ""); | ||
- static_assert(C('x').b == 2, ""); | + static_assert(C('x').b == 2, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'b' of union with active member 'c' is not allowed in a constant expression}} | |||
static_assert(C('x').c == 3, ""); | static_assert(C('x').c == 3, ""); | ||
- static_assert(C('x').d == 4, ""); | + static_assert(C('x').d == 4, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'd' of union with active member 'e' is not allowed in a constant expression}} | |||
static_assert(C('x').e == 5, ""); | static_assert(C('x').e == 5, ""); | ||
static_assert(C(1).b == 2, ""); | static_assert(C(1).b == 2, ""); | ||
- static_assert(C(1).c == 3, ""); | + static_assert(C(1).c == 3, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}} | |||
static_assert(C(1).d == 4, ""); | static_assert(C(1).d == 4, ""); | ||
- static_assert(C(1).e == 5, ""); | + static_assert(C(1).e == 5, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'e' of union with active member 'd' is not allowed in a constant expression}} | |||
static_assert(C(1.f).b == 2, ""); | static_assert(C(1.f).b == 2, ""); | ||
- static_assert(C(1.f).c == 3, ""); | + static_assert(C(1.f).c == 3, ""); | ||
- static_assert(C(1.f).e == 5, ""); // expected-error {{constant}} expected-note {{read of}} | + // expected-error@-1 {{static assertion expression is not an integral constant expression}} | ||
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}} | |||
+ static_assert(C(1.f).e == 5, ""); | |||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'e' of union with active member 'f' is not allowed in a constant expression}} | |||
static_assert(C(1.f).f == 6, ""); | static_assert(C(1.f).f == 6, ""); | ||
- static_assert(C("").a == 1, ""); | + static_assert(C("").a == 1, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'a' of union with active member 'b' is not allowed in a constant expression}} | |||
static_assert(C("").b == 2, ""); | static_assert(C("").b == 2, ""); | ||
- static_assert(C("").c == 3, ""); | + static_assert(C("").c == 3, ""); | ||
- static_assert(C("").d == 4, ""); // expected-error {{constant}} expected-note {{read of}} | + // expected-error@-1 {{static assertion expression is not an integral constant expression}} | ||
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}} | |||
+ static_assert(C("").d == 4, ""); | |||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'd' of union with active member 'e' is not allowed in a constant expression}} | |||
static_assert(C("").e == 5, ""); | static_assert(C("").e == 5, ""); | ||
- static_assert(C("").f == 6, ""); | + static_assert(C("").f == 6, ""); | ||
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} | |||
+ // expected-note@-2 {{read of member 'f' of union with active member 'e' is not allowed in a constant expression}} | |||
struct D; | struct D; | ||
extern const D d; | extern const D d; | ||
@@ -315,8 +372,10 @@ namespace std { | |||
const _E* end() const {return __begin_ + __size_;} | const _E* end() const {return __begin_ + __size_;} | ||
}; | }; | ||
} // std | } // std | ||
+#endif | |||
namespace dr1467 { // dr1467: 3.7 c++11 | namespace dr1467 { // dr1467: 3.7 c++11 | ||
+#if __cplusplus >= 201103L | |||
// Note that the change to [over.best.ics] was partially undone by DR2076; | // Note that the change to [over.best.ics] was partially undone by DR2076; | ||
// the resulting rule is tested with the tests for that change. | // the resulting rule is tested with the tests for that change. | ||
@@ -382,9 +441,12 @@ namespace dr1467 { // dr1467: 3.7 c++11 | |||
X x; | X x; | ||
X x2{x}; | X x2{x}; | ||
- void f1(int); // expected-note {{candidate function}} | + void f1(int); // #dr1467-f1 | ||
- void f1(std::initializer_list<long>) = delete; // | + void f1(std::initializer_list<long>) = delete; // #dr1467-f1-deleted | ||
- void g1() { f1({42}); } | + void g1() { f1({42}); } | ||
+ // since-cxx11-error@-1 {{call to deleted function 'f1'}} | |||
+ // since-cxx11-note@#dr1467-f1 {{candidate function}} | |||
+ // since-cxx11-note@#dr1467-f1-deleted {{candidate function has been explicitly deleted}} | |||
template <class T, class U> | template <class T, class U> | ||
struct Pair { | struct Pair { | ||
@@ -394,9 +456,12 @@ namespace dr1467 { // dr1467: 3.7 c++11 | |||
String(const char *); | String(const char *); | ||
}; | }; | ||
- void f2(Pair<const char *, const char *>); | + void f2(Pair<const char *, const char *>); // #dr1467-f2 | ||
- void f2(std::initializer_list<String>) = delete; // | + void f2(std::initializer_list<String>) = delete; // #dr1467-f2-deleted | ||
- void g2() { f2({"foo", "bar"}); } | + void g2() { f2({"foo", "bar"}); } | ||
+ // since-cxx11-error@-1 {{call to deleted function 'f2'}} | |||
+ // since-cxx11-note@#dr1467-f2 {{candidate function}} | |||
+ // since-cxx11-note@#dr1467-f2-deleted {{candidate function has been explicitly deleted}} | |||
} // dr_example | } // dr_example | ||
namespace nonaggregate { | namespace nonaggregate { | ||
@@ -453,84 +518,151 @@ namespace dr1467 { // dr1467: 3.7 c++11 | |||
} | } | ||
} // namespace NonAmbiguous | } // namespace NonAmbiguous | ||
-#if __cplusplus >= 201103L | |||
namespace StringLiterals { | namespace StringLiterals { | ||
// When the array size is 4 the call will attempt to bind an lvalue to an | // When the array size is 4 the call will attempt to bind an lvalue to an | ||
// rvalue and fail. Therefore #2 will be called. (rsmith will bring this | // rvalue and fail. Therefore #2 will be called. (rsmith will bring this | ||
// issue to CWG) | // issue to CWG) | ||
- void f(const char(&&)[4]); // expected-note 2 {{expects an rvalue}} expected-note 3 {{no known conversion}} | + void f(const char(&&)[4]); // #dr1467-f-char-4 | ||
- void f(const char(&&)[5]) = delete; // expected-note 2 {{candidate function has been explicitly deleted}} expected-note 3 {{no known conversion}} | + void f(const char(&&)[5]) = delete; // #dr1467-f-char-5 | ||
- void f(const wchar_t(&&)[4]); // expected-note {{expects an rvalue}} expected-note 4 {{no known conversion}} | + void f(const wchar_t(&&)[4]); // #dr1467-f-wchar-4 | ||
- void f(const wchar_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} expected-note 4 {{no known conversion}} | + void f(const wchar_t(&&)[5]) = delete; // #dr1467-f-wchar-5 | ||
#if __cplusplus >= 202002L | #if __cplusplus >= 202002L | ||
- void f2(const char8_t(&&)[4]); // | + void f2(const char8_t(&&)[4]); // #dr1467-f2-char8-4 | ||
- void f2(const char8_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} | + void f2(const char8_t(&&)[5]) = delete; // #dr1467-f2-char8-5 | ||
#endif | #endif | ||
- void f(const char16_t(&&)[4]); // expected-note {{expects an rvalue}} expected-note 4 {{no known conversion}} | + void f(const char16_t(&&)[4]); // #dr1467-f-char16-4 | ||
- void f(const char16_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} expected-note 4 {{no known conversion}} | + void f(const char16_t(&&)[5]) = delete; // #dr1467-f-char16-5 | ||
- void f(const char32_t(&&)[4]); // expected-note {{expects an rvalue}} expected-note 4 {{no known conversion}} | + void f(const char32_t(&&)[4]); // #dr1467-f-char32-4 | ||
- void f(const char32_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} expected-note 4 {{no known conversion}} | + void f(const char32_t(&&)[5]) = delete; // #dr1467-f-char32-5 | ||
void g() { | void g() { | ||
- f({"abc"}); | + f({"abc"}); | ||
- | + // since-cxx11-error@-1 {{call to deleted function 'f'}} | ||
- f({L"abc"}); // expected-error {{call to deleted function 'f'}} | + // since-cxx11-note@#dr1467-f-char-5 {{candidate function has been explicitly deleted}} | ||
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: expects an rvalue for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}} | |||
+ f({((("abc")))}); | |||
+ // since-cxx11-error@-1 {{call to deleted function 'f'}} | |||
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function has been explicitly deleted}} | |||
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: expects an rvalue for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}} | |||
+ f({L"abc"}); | |||
+ // since-cxx11-error@-1 {{call to deleted function 'f'}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function has been explicitly deleted}} | |||
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: expects an rvalue for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char32_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char32_t' for 1st argument}} | |||
#if __cplusplus >= 202002L | #if __cplusplus >= 202002L | ||
- f2({u8"abc"}); | + f2({u8"abc"}); | ||
+ // since-cxx20-error@-1 {{call to deleted function 'f2'}} | |||
+ // since-cxx20-note@#dr1467-f2-char8-5 {{candidate function has been explicitly deleted}} | |||
+ // since-cxx20-note@#dr1467-f2-char8-4 {{candidate function not viable: expects an rvalue for 1st argument}} | |||
#endif | #endif | ||
- f({uR"(abc)"}); | + f({uR"(abc)"}); | ||
- | + // since-cxx11-error@-1 {{call to deleted function 'f'}} | ||
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function has been explicitly deleted}} | |||
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: expects an rvalue for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char32_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char32_t' for 1st argument}} | |||
+ f({(UR"(abc)")}); | |||
+ // since-cxx11-error@-1 {{call to deleted function 'f'}} | |||
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function has been explicitly deleted}} | |||
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const wchar_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char16_t' for 1st argument}} | |||
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: expects an rvalue for 1st argument}} | |||
} | } | ||
} // namespace StringLiterals | } // namespace StringLiterals | ||
#endif | #endif | ||
} // dr1467 | } // dr1467 | ||
-namespace dr1479 { // dr1479: | +namespace dr1479 { // dr1479: 3.1 | ||
- int operator"" _a(const char*, std::size_t = 0); // expected-error {{literal operator cannot have a default argument}} | +#if __cplusplus >= 201103L | ||
+ int operator"" _a(const char*, std::size_t = 0); | |||
+ // since-cxx11-error@-1 {{literal operator cannot have a default argument}} | |||
+#endif | |||
} | } | ||
-namespace dr1482 { // dr1482: | +namespace dr1482 { // dr1482: 3.0 | ||
// NB: sup 2516, test reused there | // NB: sup 2516, test reused there | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
template <typename T> struct S { | template <typename T> struct S { | ||
typedef char I; | typedef char I; | ||
}; | }; | ||
enum E2 : S<E2>::I { e }; | enum E2 : S<E2>::I { e }; | ||
-// | +// since-cxx11-error@-1 {{use of undeclared identifier 'E2'}} | ||
#endif | #endif | ||
} // namespace dr1482 | } // namespace dr1482 | ||
namespace dr1490 { // dr1490: 3.7 c++11 | namespace dr1490 { // dr1490: 3.7 c++11 | ||
+#if __cplusplus >= 201103L | |||
// List-initialization from a string literal | // List-initialization from a string literal | ||
- char s[4]{"abc"}; | + char s[4]{"abc"}; // Ok | ||
- std::initializer_list<char>{"abc"}; | + std::initializer_list<char>{"abc"}; | ||
+ // since-cxx11-error@-1 {{expected unqualified-id}}} | |||
+#endif | |||
} // dr1490 | } // dr1490 | ||
namespace dr1495 { // dr1495: 4 | namespace dr1495 { // dr1495: 4 | ||
+#if __cplusplus >= 201103L | |||
// Deduction succeeds in both directions. | // Deduction succeeds in both directions. | ||
- template<typename T, typename U> struct A {}; // | + template<typename T, typename U> struct A {}; // #dr1495-A | ||
- template<typename T, typename U> struct A<U, T> {}; | + template<typename T, typename U> struct A<U, T> {}; | ||
+ // since-cxx11-error@-1 {{class template partial specialization is not more specialized than the primary template}} | |||
+ // since-cxx11-note@#dr1495-A {{template is declared here}} | |||
// Primary template is more specialized. | // Primary template is more specialized. | ||
- template<typename, typename...> struct B {}; // | + template<typename, typename...> struct B {}; // #dr1495-B | ||
- template<typename ...Ts> struct B<Ts...> {}; | + template<typename ...Ts> struct B<Ts...> {}; | ||
+ // since-cxx11-error@-1 {{class template partial specialization is not more specialized than the primary template}} | |||
+ // since-cxx11-note@#dr1495-B {{template is declared here}} | |||
// Deduction fails in both directions. | // Deduction fails in both directions. | ||
- template<int, typename, typename ...> struct C {}; // | + template<int, typename, typename ...> struct C {}; // #dr1495-C | ||
- template<typename ...Ts> struct C<0, Ts...> {}; | + template<typename ...Ts> struct C<0, Ts...> {}; | ||
+ // since-cxx11-error@-1 {{class template partial specialization is not more specialized than the primary template}} | |||
+ // since-cxx11-note@#dr1495-C {{template is declared here}} | |||
#if __cplusplus >= 201402L | #if __cplusplus >= 201402L | ||
// Deduction succeeds in both directions. | // Deduction succeeds in both directions. | ||
- template<typename T, typename U> int a; // | + template<typename T, typename U> int a; // #dr1495-a | ||
- template<typename T, typename U> int a<U, T>; | + template<typename T, typename U> int a<U, T>; | ||
+ // since-cxx14-error@-1 {{variable template partial specialization is not more specialized than the primary template}} | |||
+ // since-cxx14-note@#dr1495-a {{template is declared here}} | |||
// Primary template is more specialized. | // Primary template is more specialized. | ||
- template<typename, typename...> int b; // | + template<typename, typename...> int b; // #dr1495-b | ||
- template<typename ...Ts> int b<Ts...>; | + template<typename ...Ts> int b<Ts...>; | ||
+ // since-cxx14-error@-1 {{variable template partial specialization is not more specialized than the primary template}} | |||
+ // since-cxx14-note@#dr1495-b {{template is declared here}} | |||
// Deduction fails in both directions. | // Deduction fails in both directions. | ||
- template<int, typename, typename ...> int c; // | + template<int, typename, typename ...> int c; // #dr1495-c | ||
- template<typename ...Ts> int c<0, Ts...>; | + template<typename ...Ts> int c<0, Ts...>; | ||
+ // since-cxx14-error@-1 {{variable template partial specialization is not more specialized than the primary template}} | |||
+ // since-cxx14-note@#dr1495-c {{template is declared here}} | |||
+#endif | |||
#endif | #endif | ||
} | } | ||
@@ -544,5 +676,3 @@ struct A { | |||
static_assert(__is_trivial(A), ""); | static_assert(__is_trivial(A), ""); | ||
#endif | #endif | ||
} | } | ||
- | |||
-#endif |
@@ -1,13 +1,18 @@ | |||
// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11-14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected, | +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11-14,cxx14-17 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,cxx17 -fexceptions -fcxx-exceptions -pedantic-errors | +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors | ||
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors | |||
namespace dr1512 { // dr1512: 4 | namespace dr1512 { // dr1512: 4 | ||
void f(char *p) { | void f(char *p) { | ||
- if (p > 0) {} | + if (p > 0) {} | ||
+ // expected-error@-1 {{ordered comparison between pointer and zero ('char *' and 'int')}} | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- if (p > nullptr) {} | + if (p > nullptr) {} | ||
+ // since-cxx11-error@-1 {{invalid operands to binary expression ('char *' and 'std::nullptr_t')}} | |||
#endif | #endif | ||
} | } | ||
bool g(int **x, const int **y) { | bool g(int **x, const int **y) { | ||
@@ -28,10 +33,20 @@ namespace dr1512 { // dr1512: 4 | |||
template<typename A, typename B, typename C> void composite_pointe | template<typename A, typename B, typename C> void composite_pointe | ||
composite_pointe | composite_pointe | ||
- typedef __typeof(val<A>() < val<B>()) cmp; | + typedef __typeof(val<A>() < val<B>()) cmp; // #dr1512-lt | ||
- typedef __typeof(val<A>() <= val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}} | + // since-cxx17-warning@#dr1512-lt {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} | ||
- typedef __typeof(val<A>() > val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}} | + // since-cxx17-note@#dr1512-noexcept-1st {{in instantiation of function template specialization 'dr1512::composite_pointe | ||
- typedef __typeof(val<A>() >= val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}} | + // since-cxx17-warning@#dr1512-lt {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} | ||
+ // since-cxx17-note@#dr1512-noexcept-2nd {{in instantiation of function template specialization 'dr1512::composite_pointe | |||
+ typedef __typeof(val<A>() <= val<B>()) cmp; | |||
+ // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} | |||
+ // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} | |||
+ typedef __typeof(val<A>() > val<B>()) cmp; | |||
+ // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} | |||
+ // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} | |||
+ typedef __typeof(val<A>() >= val<B>()) cmp; | |||
+ // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} | |||
+ // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} | |||
typedef bool cmp; | typedef bool cmp; | ||
} | } | ||
@@ -77,10 +92,11 @@ namespace dr1512 { // dr1512: 4 | |||
composite_pointe | composite_pointe | ||
no_composite_poi | no_composite_poi | ||
no_composite_poi | no_composite_poi | ||
+ // since-cxx20-warning@-1 {{volatile-qualified return type 'volatile int' is deprecated}} | |||
-#if __cplusplus | +#if __cplusplus >= 201703L | ||
- composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>(); // | + composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>(); // #dr1512-noexcept-1st | ||
- composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>(); // | + composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>(); // #dr1512-noexcept-2nd | ||
composite_pointe | composite_pointe | ||
composite_pointe | composite_pointe | ||
// FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'. | // FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'. | ||
@@ -113,24 +129,40 @@ namespace dr1512 { // dr1512: 4 | |||
} | } | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- template<typename T> struct Wrap { operator T(); }; // expected-note 4{{converted to type 'std::nullptr_t'}} expected-note 4{{converted to type 'int *'}} | + template<typename T> struct Wrap { operator T(); }; // #dr1512-Wrap | ||
void test_overload() { | void test_overload() { | ||
using nullptr_t = decltype(nullptr); | using nullptr_t = decltype(nullptr); | ||
void(Wrap<nullptr_t>() == Wrap<nullptr_t>()); | void(Wrap<nullptr_t>() == Wrap<nullptr_t>()); | ||
void(Wrap<nullptr_t>() != Wrap<nullptr_t>()); | void(Wrap<nullptr_t>() != Wrap<nullptr_t>()); | ||
- void(Wrap<nullptr_t>() < Wrap<nullptr_t>()); | + void(Wrap<nullptr_t>() < Wrap<nullptr_t>()); | ||
- void(Wrap<nullptr_t>() > Wrap<nullptr_t>()); // expected-error {{invalid operands}} | + // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}} | ||
- void(Wrap<nullptr_t>() | + void(Wrap<nullptr_t>() > Wrap<nullptr_t>()); | ||
- void(Wrap<nullptr_t>() >= Wrap<nullptr_t>()); // expected-error {{invalid operands}} | + // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}} | ||
+ void(Wrap<nullptr_t>() <= Wrap<nullptr_t>()); | |||
+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}} | |||
+ void(Wrap<nullptr_t>() >= Wrap<nullptr_t>()); | |||
+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}} | |||
// Under dr1213, this is ill-formed: we select the builtin operator<(int*, int*) | // Under dr1213, this is ill-formed: we select the builtin operator<(int*, int*) | ||
// but then only convert as far as 'nullptr_t', which we then can't convert to 'int*'. | // but then only convert as far as 'nullptr_t', which we then can't convert to 'int*'. | ||
void(Wrap<nullptr_t>() == Wrap<int*>()); | void(Wrap<nullptr_t>() == Wrap<int*>()); | ||
void(Wrap<nullptr_t>() != Wrap<int*>()); | void(Wrap<nullptr_t>() != Wrap<int*>()); | ||
- void(Wrap<nullptr_t>() < Wrap<int*>()); | + void(Wrap<nullptr_t>() < Wrap<int*>()); | ||
- void(Wrap<nullptr_t>() > Wrap<int*>()); // expected-error {{invalid operands}} | + // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<int *>')}} | ||
- void(Wrap<nullptr_t>() <= Wrap<int*>()); // expected-error {{invalid operands}} | + // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} | ||
- void(Wrap<nullptr_t>() >= Wrap<int*>()); // expected-error {{invalid operands}} | + // since-cxx11-note@#dr1512-Wrap {{second operand was implicitly converted to type 'int *'}} | ||
+ void(Wrap<nullptr_t>() > Wrap<int*>()); | |||
+ // since-cxx11-error@-1 {{invalid operands}} | |||
+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} | |||
+ // since-cxx11-note@#dr1512-Wrap{{second operand was implicitly converted to type 'int *'}} | |||
+ void(Wrap<nullptr_t>() <= Wrap<int*>()); | |||
+ // since-cxx11-error@-1 {{invalid operands}} | |||
+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} | |||
+ // since-cxx11-note@#dr1512-Wrap {{second operand was implicitly converted to type 'int *'}} | |||
+ void(Wrap<nullptr_t>() >= Wrap<int*>()); | |||
+ // since-cxx11-error@-1 {{invalid operands}} | |||
+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} | |||
+ // since-cxx11-note@#dr1512-Wrap {{second operand was implicitly converted to type 'int *'}} | |||
} | } | ||
#endif | #endif | ||
} | } | ||
@@ -138,8 +170,10 @@ namespace dr1512 { // dr1512: 4 | |||
namespace dr1514 { // dr1514: 11 | namespace dr1514 { // dr1514: 11 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
struct S { | struct S { | ||
- enum E : int {}; // | + enum E : int {}; // #dr1514-E | ||
- enum E : int {}; | + enum E : int {}; | ||
+ // since-cxx11-error@-1 {{redefinition of 'E'}} | |||
+ // since-cxx11-note@#dr1514-E {{previous definition is here}} | |||
}; | }; | ||
S::E se; // OK, complete type, not zero-width bitfield. | S::E se; // OK, complete type, not zero-width bitfield. | ||
@@ -149,91 +183,142 @@ namespace dr1514 { // dr1514: 11 | |||
namespace dr1518 { // dr1518: 4 | namespace dr1518 { // dr1518: 4 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
-struct Z0 { // expected-note 0+ {{candidate}} | +struct Z0 { // #dr1518-Z0 | ||
- explicit Z0() = default; // | + explicit Z0() = default; // #dr1518-Z0-ctor | ||
}; | }; | ||
-struct Z { // expected-note 0+ {{candidate}} | +struct Z { // #dr1518-Z | ||
- explicit Z(); // | + explicit Z(); // #dr1518-Z-ctor | ||
- explicit Z(int); // | + explicit Z(int); // #dr1518-Z-int | ||
- explicit Z(int, int); // | + explicit Z(int, int); // #dr1518-Z-int-int | ||
}; | }; | ||
-template <class T> int Eat(T); // | +template <class T> int Eat(T); // #dr1518-Eat | ||
Z0 a; | Z0 a; | ||
Z0 b{}; | Z0 b{}; | ||
-Z0 c = {}; // expected-error {{explicit in copy-initialization}} | +Z0 c = {}; | ||
-int i = Eat<Z0>({}); // expected-error {{no matching function for call to 'Eat'}} | +// since-cxx11-error@-1 {{chosen constructor is explicit in copy-initialization}} | ||
- | +// since-cxx11-note@#dr1518-Z0-ctor {{explicit constructor declared here}} | ||
-Z c2 = {}; // expected-error {{explicit in copy-initialization}} | +int i = Eat<Z0>({}); | ||
-int i2 = Eat<Z>({}); // expected-error {{no matching function for call to 'Eat'}} | +// since-cxx11-error@-1 {{no matching function for call to 'Eat'}} | ||
-Z a1 = 1; // expected-error {{no viable conversion}} | +// since-cxx11-note@#dr1518-Eat {{candidate function template not viable: cannot convert initializer list argument to 'Z0'}} | ||
+ | |||
+Z c2 = {}; | |||
+// since-cxx11-error@-1 {{chosen constructor is explicit in copy-initialization}} | |||
+// since-cxx11-note@#dr1518-Z-ctor {{explicit constructor declared here}} | |||
+int i2 = Eat<Z>({}); | |||
+// since-cxx11-error@-1 {{no matching function for call to 'Eat'}} | |||
+// since-cxx11-note@#dr1518-Eat {{candidate function template not viable: cannot convert initializer list argument to 'Z'}} | |||
+Z a1 = 1; | |||
+// since-cxx11-error@-1 {{no viable conversion from 'int' to 'Z'}} | |||
+// since-cxx11-note@#dr1518-Z {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Z &' for 1st argument}} | |||
+// since-cxx11-note@#dr1518-Z {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'Z &&' for 1st argument}} | |||
+// since-cxx11-note@#dr1518-Z-int {{explicit constructor is not a candidate}} | |||
Z a3 = Z(1); | Z a3 = Z(1); | ||
Z a2(1); | Z a2(1); | ||
Z *p = new Z(1); | Z *p = new Z(1); | ||
Z a4 = (Z)1; | Z a4 = (Z)1; | ||
Z a5 = static_cast<Z>(1); | Z a5 = static_cast<Z>(1); | ||
-Z a6 = {4, 3}; | +Z a6 = {4, 3}; | ||
+// since-cxx11-error@-1 {{chosen constructor is explicit in copy-initialization}} | |||
+// since-cxx11-note@#dr1518-Z-int-int {{explicit constructor declared here}} | |||
-struct UserProvidedBaseCtor { // | +struct UserProvidedBaseCtor { // #dr1518-U | ||
UserProvidedBase | UserProvidedBase | ||
}; | }; | ||
-struct DoesntInheritCtor : UserProvidedBaseCtor { // | +struct DoesntInheritCtor : UserProvidedBaseCtor { // #dr1518-D-U | ||
int x; | int x; | ||
}; | }; | ||
DoesntInheritCto | DoesntInheritCto | ||
-#if __cplusplus <= 201402L | +// cxx11-14-error@-1 {{no matching constructor for initialization of 'DoesntInheritCto | ||
-// expected-error@-2 {{no matching constructor}} | +// cxx11-14-note@#dr1518-D-U {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}} | ||
-#endif | +// cxx11-14-note@#dr1518-D-U {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}} | ||
- | +// cxx11-14-note@#dr1518-D-U {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided}} | ||
-struct BaseCtor { BaseCtor() = default; }; // expected-note 0+ {{candidate}} | + | ||
-struct InheritsCtor : BaseCtor { // expected-note 1+ {{candidate}} | +struct BaseCtor { BaseCtor() = default; }; // #dr1518-BC | ||
- using BaseCtor::BaseCtor; // expected-note 2 {{inherited here}} | +struct InheritsCtor : BaseCtor { // #dr1518-I | ||
+ using BaseCtor::BaseCtor; // #dr1518-I-using | |||
int x; | int x; | ||
}; | }; | ||
-InheritsCtor II = {{}, 42}; | +InheritsCtor II = {{}, 42}; | ||
+// since-cxx11-error@-1 {{no matching constructor for initialization of 'InheritsCtor'}} | |||
+// since-cxx11-note@#dr1518-BC {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}} | |||
+// since-cxx11-note@#dr1518-I-using {{constructor from base class 'BaseCtor' inherited here}} | |||
+// since-cxx11-note@#dr1518-BC {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}} | |||
+// since-cxx11-note@#dr1518-I-using {{constructor from base class 'BaseCtor' inherited here}} | |||
+// since-cxx11-note@#dr1518-I {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}} | |||
+// since-cxx11-note@#dr1518-I {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}} | |||
+// since-cxx11-note@#dr1518-I {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided}} | |||
namespace std_example { | namespace std_example { | ||
struct A { | struct A { | ||
- explicit A() = default; // | + explicit A() = default; // #dr1518-A | ||
}; | }; | ||
struct B : A { | struct B : A { | ||
- explicit B() = default; // | + explicit B() = default; // #dr1518-B | ||
}; | }; | ||
struct C { | struct C { | ||
- explicit C(); // | + explicit C(); // #dr1518-C | ||
}; | }; | ||
struct D : A { | struct D : A { | ||
C c; | C c; | ||
- explicit D() = default; // | + explicit D() = default; // #dr1518-D | ||
}; | }; | ||
template <typename T> void f() { | template <typename T> void f() { | ||
T t; // ok | T t; // ok | ||
T u{}; // ok | T u{}; // ok | ||
- T v = {}; // | + T v = {}; // #dr1518-v | ||
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-f-A {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::A>' requested here}} | |||
+ // since-cxx11-note@#dr1518-A {{explicit constructor declared here}} | |||
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-f-B {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::B>' requested here}} | |||
+ // since-cxx11-note@#dr1518-B {{explicit constructor declared here}} | |||
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-f-C {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::C>' requested here}} | |||
+ // since-cxx11-note@#dr1518-C {{explicit constructor declared here}} | |||
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-f-D {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::D>' requested here}} | |||
+ // since-cxx11-note@#dr1518-D {{explicit constructor declared here}} | |||
} | } | ||
template <typename T> void g() { | template <typename T> void g() { | ||
- void x(T t); // | + void x(T t); // #dr1518-x | ||
- x({}); // expected-error 4{{explicit}} | + x({}); // #dr1518-x-call | ||
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-g-A {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::A>' requested here}} | |||
+ // since-cxx11-note@#dr1518-A {{explicit constructor declared here}} | |||
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}} | |||
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-g-B {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::B>' requested here}} | |||
+ // since-cxx11-note@#dr1518-B {{explicit constructor declared here}} | |||
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}} | |||
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-g-C {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::C>' requested here}} | |||
+ // since-cxx11-note@#dr1518-C {{explicit constructor declared here}} | |||
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}} | |||
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}} | |||
+ // since-cxx11-note@#dr1518-g-D {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::D>' requested here}} | |||
+ // since-cxx11-note@#dr1518-D {{explicit constructor declared here}} | |||
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}} | |||
} | } | ||
void test() { | void test() { | ||
- f<A>(); // expected-note {{instantiation of}} | + f<A>(); // #dr1518-f-A | ||
- f<B>(); // expected-note {{instantiation of}} | + f<B>(); // #dr1518-f-B | ||
- f<C>(); // expected-note {{instantiation of}} | + f<C>(); // #dr1518-f-C | ||
- f<D>(); // expected-note {{instantiation of}} | + f<D>(); // #dr1518-f-D | ||
- g<A>(); // expected-note {{instantiation of}} | + g<A>(); // #dr1518-g-A | ||
- g<B>(); // expected-note {{instantiation of}} | + g<B>(); // #dr1518-g-B | ||
- g<C>(); // expected-note {{instantiation of}} | + g<C>(); // #dr1518-g-C | ||
- g<D>(); // expected-note {{instantiation of}} | + g<D>(); // #dr1518-g-D | ||
} | } | ||
} | } | ||
-#endif | +#endif // __cplusplus >= 201103L | ||
} | } | ||
-namespace dr1550 { // dr1550: | +namespace dr1550 { // dr1550: 3.4 | ||
int f(bool b, int n) { | int f(bool b, int n) { | ||
return (b ? (throw 0) : n) + (b ? n : (throw 0)); | return (b ? (throw 0) : n) + (b ? n : (throw 0)); | ||
} | } | ||
@@ -242,13 +327,16 @@ namespace dr1550 { // dr1550: yes | |||
namespace dr1558 { // dr1558: 12 | namespace dr1558 { // dr1558: 12 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
template<class T, class...> using first_of = T; | template<class T, class...> using first_of = T; | ||
- template<class T> first_of<void, typename T::type> f(int); // | + template<class T> first_of<void, typename T::type> f(int); // #dr1558-f | ||
- template<class T> void f(...) = delete; // | + template<class T> void f(...) = delete; // #dr1558-f-deleted | ||
struct X { typedef void type; }; | struct X { typedef void type; }; | ||
void test() { | void test() { | ||
f<X>(0); | f<X>(0); | ||
- f<int>(0); | + f<int>(0); | ||
+ // since-cxx11-error@-1 {{call to deleted function 'f'}} | |||
+ // since-cxx11-note@#dr1558-f-deleted {{candidate function [with T = int] has been explicitly deleted}} | |||
+ // since-cxx11-note@#dr1558-f {{candidate template ignored: substitution failure [with T = int]: type 'int' cannot be used prior to '::' because it has no members}} | |||
} | } | ||
#endif | #endif | ||
} | } | ||
@@ -283,17 +371,25 @@ namespace dr1573 { // dr1573: 3.9 | |||
struct C { C(); constexpr C(int) {} }; | struct C { C(); constexpr C(int) {} }; | ||
struct D : C { using C::C; }; | struct D : C { using C::C; }; | ||
constexpr D d = D(0); // ok | constexpr D d = D(0); // ok | ||
- struct E : C { using C::C; A a; }; // | + struct E : C { using C::C; A a; }; // #dr1573-E | ||
- constexpr E e = E(0); | + constexpr E e = E(0); | ||
+ // since-cxx11-error@-1 {{constexpr variable cannot have non-literal type 'const E'}} | |||
+ // since-cxx11-note@#dr1573-E {{'E' is not literal because it has data member 'a' of non-literal type 'A'}} | |||
+ | |||
// FIXME: This diagnostic is pretty bad; we should explain that the problem | // FIXME: This diagnostic is pretty bad; we should explain that the problem | ||
// is that F::c would be initialized by a non-constexpr constructor. | // is that F::c would be initialized by a non-constexpr constructor. | ||
- struct F : C { using C::C; C c; }; // | + struct F : C { using C::C; C c; }; // #dr1573-F | ||
- constexpr F f = F(0); | + constexpr F f = F(0); | ||
+ // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}} | |||
+ // since-cxx11-note@-2 {{constructor inherited from base class 'C' cannot be used in a constant expression; derived class cannot be implicitly initialized}} | |||
+ // since-cxx11-note@#dr1573-F {{declared here}} | |||
// inherited constructor is effectively deleted if the user-written constructor would be | // inherited constructor is effectively deleted if the user-written constructor would be | ||
struct G { G(int); }; | struct G { G(int); }; | ||
- struct H : G { using G::G; G g; }; // expected-note {{constructor inherited by 'H' is implicitly deleted because field 'g' has no default constructor}} | + struct H : G { using G::G; G g; }; // #dr1573-H | ||
- H h(0); // expected-error {{constructor inherited by 'H' from base class 'G' is implicitly deleted}} | + H h(0); | ||
+ // since-cxx11-error@-1 {{constructor inherited by 'H' from base class 'G' is implicitly deleted}} | |||
+ // since-cxx11-note@#dr1573-H {{constructor inherited by 'H' is implicitly deleted because field 'g' has no default constructor}} | |||
#endif | #endif | ||
} | } | ||
@@ -336,13 +432,15 @@ namespace std { | |||
typedef basic_string<char> string; | typedef basic_string<char> string; | ||
} // std | } // std | ||
+#endif | |||
namespace dr1579 { // dr1579: 3.9 | namespace dr1579 { // dr1579: 3.9 | ||
+#if __cplusplus >= 201103L | |||
template<class T> | template<class T> | ||
struct GenericMoveOnly { | struct GenericMoveOnly { | ||
GenericMoveOnly(); | GenericMoveOnly(); | ||
- template<class U> GenericMoveOnly(const GenericMoveOnly<U> &) = delete; // | + template<class U> GenericMoveOnly(const GenericMoveOnly<U> &) = delete; // #dr1579-deleted-U | ||
- GenericMoveOnly(const int &) = delete; // | + GenericMoveOnly(const int &) = delete; // #dr1579-deleted-int | ||
template<class U> GenericMoveOnly(GenericMoveOnly<U> &&); | template<class U> GenericMoveOnly(GenericMoveOnly<U> &&); | ||
GenericMoveOnly(int &&); | GenericMoveOnly(int &&); | ||
}; | }; | ||
@@ -369,17 +467,29 @@ GenericMoveOnly< | |||
extern GenericMoveOnly<char> ExternMove; | extern GenericMoveOnly<char> ExternMove; | ||
if (0) | if (0) | ||
- return AnInt; | + return AnInt; | ||
+ // since-cxx11-error@-1 {{conversion function from 'int' to 'GenericMoveOnly<float>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-int {{'GenericMoveOnly' has been explicitly marked deleted here}} | |||
else if (0) | else if (0) | ||
- return GlobalMO; | + return GlobalMO; | ||
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}} | |||
else if (0) | else if (0) | ||
- return StaticMove; | + return StaticMove; | ||
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}} | |||
else if (0) | else if (0) | ||
- return ExternMove; | + return ExternMove; | ||
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}} | |||
else if (0) | else if (0) | ||
- return AnInt; | + return AnInt; | ||
+ // since-cxx11-error@-1 {{conversion function from 'int' to 'GenericMoveOnly<float>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-int {{'GenericMoveOnly' has been explicitly marked deleted here}} | |||
else | else | ||
- return CharMO; | + return CharMO; | ||
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}} | |||
} | } | ||
auto DR1579_lambda_va | auto DR1579_lambda_va | ||
@@ -389,24 +499,34 @@ auto DR1579_lambda_va | |||
auto DR1579_lambda_in | auto DR1579_lambda_in | ||
static GenericMoveOnly<float> mo; | static GenericMoveOnly<float> mo; | ||
- return mo; | + return mo; | ||
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<float>' to 'GenericMoveOnly<char>' invokes a deleted function}} | |||
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<float>' has been explicitly marked deleted here}} | |||
}; | }; | ||
+#endif | |||
} // end namespace dr1579 | } // end namespace dr1579 | ||
namespace dr1584 { | namespace dr1584 { | ||
+#if __cplusplus >= 201103L | |||
// Deducing function types from cv-qualified types | // Deducing function types from cv-qualified types | ||
- template<typename T> void f(const T *); // | + template<typename T> void f(const T *); // #dr1584-f | ||
template<typename T> void g(T *, const T * = 0); | template<typename T> void g(T *, const T * = 0); | ||
- template<typename T> void h(T *) { T::error; } | + template<typename T> void h(T *) { T::error; } | ||
+ // since-cxx11-error@-1 {{type 'void ()' cannot be used prior to '::' because it has no members}} | |||
+ // since-cxx11-note@#dr1584-h {{in instantiation of function template specialization 'dr1584::h<void ()>' requested here}} | |||
template<typename T> void h(const T *); | template<typename T> void h(const T *); | ||
void i() { | void i() { | ||
- f(&i); // expected-error {{no matching function}} | + f(&i); | ||
+ // since-cxx11-error@-1 {{no matching function for call to 'f'}} | |||
+ // since-cxx11-note@#dr1584-f {{candidate template ignored: could not match 'const T *' against 'void (*)()'}} | |||
g(&i); | g(&i); | ||
- h(&i); // | + h(&i); // #dr1584-h | ||
} | } | ||
+#endif | |||
} | } | ||
namespace dr1589 { // dr1589: 3.7 c++11 | namespace dr1589 { // dr1589: 3.7 c++11 | ||
+#if __cplusplus >= 201103L | |||
// Ambiguous ranking of list-initialization sequences | // Ambiguous ranking of list-initialization sequences | ||
void f0(long, int=0); // Would makes selection of #0 ambiguous | void f0(long, int=0); // Would makes selection of #0 ambiguous | ||
@@ -425,25 +545,35 @@ namespace dr1589 { // dr1589: 3.7 c++11 | |||
void g2() { f2({"foo","bar"}); } // chooses #4 | void g2() { f2({"foo","bar"}); } // chooses #4 | ||
namespace with_error { | namespace with_error { | ||
- void f0(long); | + void f0(long); | ||
- void f0(std::initializer_list<int>); | + void f0(std::initializer_list<int>); // #dr1589-f0-ilist | ||
- void f0(std::initializer_list<int>, int = 0); // | + void f0(std::initializer_list<int>, int = 0); // #dr1589-f0-ilist-int | ||
- void g0() { f0({1L}); } | + void g0() { f0({1L}); } | ||
- | + // since-cxx11-error@-1 {{call to 'f0' is ambiguous}} | ||
- void f1(int); // #1 | + // since-cxx11-note@#dr1589-f0-ilist {{candidate function}} | ||
- void f1(std::initializer_list | + // since-cxx11-note@#dr1589-f0-ilist-int {{candidate function}} | ||
- void f1(std::initializer_list | + | ||
- void g1() { f1({42}); } // expected-error{{call to 'f1' is ambiguous}} | + void f1(int); | ||
- | + void f1(std::initializer_list | ||
- void f2(std::pair<const char*, const char*>); // #3 | + void f1(std::initializer_list | ||
- void f2(std::initializer_list | + void g1() { f1({42}); } | ||
- void f2(std::initializer_list | + // since-cxx11-error@-1 {{call to 'f1' is ambiguous}} | ||
- void g2() { f2({"foo","bar"}); } // expected-error{{call to 'f2' is ambiguous}} | + // since-cxx11-note@#dr1589-f1-ilist {{candidate function}} | ||
+ // since-cxx11-note@#dr1589-f1-ilist-long {{candidate function}} | |||
+ | |||
+ void f2(std::pair<const char*, const char*>); | |||
+ void f2(std::initializer_list | |||
+ void f2(std::initializer_list | |||
+ void g2() { f2({"foo","bar"}); } | |||
+ // since-cxx11-error@-1 {{call to 'f2' is ambiguous}} | |||
+ // since-cxx11-note@#dr1589-f2-ilist {{candidate function}} | |||
+ // since-cxx11-note@#dr1589-f2-ilist-int {{candidate function}} | |||
} | } | ||
- | +#endif | ||
} // dr1589 | } // dr1589 | ||
-namespace dr1591 { //dr1591. Deducing array bound and element type from initializer list | +namespace dr1591 { //dr1591. Deducing array bound and element type from initializer list | ||
+#if __cplusplus >= 201103L | |||
template<class T, int N> int h(T const(&)[N]); | template<class T, int N> int h(T const(&)[N]); | ||
int X = h({1,2,3}); // T deduced to int, N deduced to 3 | int X = h({1,2,3}); // T deduced to int, N deduced to 3 | ||
@@ -451,8 +581,10 @@ namespace dr1591 { //dr1591. Deducing array bound and element type from initial | |||
int Y = j({42}); // T deduced to int, array bound not considered | int Y = j({42}); // T deduced to int, array bound not considered | ||
struct Aggr { int i; int j; }; | struct Aggr { int i; int j; }; | ||
- template<int N> int k(Aggr const(&)[N]); // | + template<int N> int k(Aggr const(&)[N]); // #dr1591-k | ||
- int Y0 = k({1,2,3}); | + int Y0 = k({1,2,3}); | ||
+ // since-cxx11-error@-1 {{no matching function for call to 'k'}} | |||
+ // since-cxx11-note@#dr1591-k {{candidate function [with N = 3] not viable: no known conversion from 'int' to 'const Aggr' for 1st argument}} | |||
int Z = k({{1},{2},{3}}); // OK, N deduced to 3 | int Z = k({{1},{2},{3}}); // OK, N deduced to 3 | ||
template<int M, int N> int m(int const(&)[M][N]); | template<int M, int N> int m(int const(&)[M][N]); | ||
@@ -463,54 +595,64 @@ namespace dr1591 { //dr1591. Deducing array bound and element type from initial | |||
namespace check_multi_dim_ | namespace check_multi_dim_ | ||
- template<class T, int N, int M, int O> int ***f(const T (&a)[N][M][O]); // | + template<class T, int N, int M, int O> int ***f(const T (&a)[N][M][O]); // #dr1591-f-3 | ||
- template<class T, int N, int M> int **f(const T (&a)[N][M]); // | + template<class T, int N, int M> int **f(const T (&a)[N][M]); // #dr1591-f-2 | ||
- template<class T, int N> int *f(const T (&a)[N]); // | + template<class T, int N> int *f(const T (&a)[N]); // #dr1591-f-1 | ||
int ***p3 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } }); | int ***p3 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } }); | ||
- int ***p33 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } }); | + int ***p33 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } }); | ||
+ // since-cxx11-error@-1 {{no matching function for call to 'f'}} | |||
+ // since-cxx11-note@#dr1591-f-2 {{candidate template ignored: couldn't infer template argument 'T'}} | |||
+ // since-cxx11-note@#dr1591-f-1 {{candidate template ignored: couldn't infer template argument 'T'}} | |||
+ // since-cxx11-note@#dr1591-f-3 {{candidate template ignored: deduced conflicting values for parameter 'O' (2 vs. 3)}} | |||
int **p2 = f({ {1,2,3}, {3, 4, 5} }); | int **p2 = f({ {1,2,3}, {3, 4, 5} }); | ||
int **p22 = f({ {1,2}, {3, 4} }); | int **p22 = f({ {1,2}, {3, 4} }); | ||
int *p1 = f({1, 2, 3}); | int *p1 = f({1, 2, 3}); | ||
} | } | ||
namespace check_multi_dim_ | namespace check_multi_dim_ | ||
- template<class T, int N, int M, int O> int *** | + template<class T, int N, int M, int O> int ***g(T (&&a)[N][M][O]); // #dr1591-g-3 | ||
- template<class T, int N, int M> int ** | + template<class T, int N, int M> int **g(T (&&a)[N][M]); // #dr1591-g-2 | ||
- template<class T, int N> int * | + template<class T, int N> int *g(T (&&a)[N]); // #dr1591-g-1 | ||
- int ***p3 = | + int ***p3 = g({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } }); | ||
- int ***p33 = | + int ***p33 = g({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } }); | ||
- int **p2 = f({ {1,2,3}, {3, 4, 5} }); | + // since-cxx11-error@-1 {{no matching function for call to 'g'}} | ||
- int **p22 = f({ {1,2}, {3, 4} }); | + // since-cxx11-note@#dr1591-g-2 {{candidate template ignored: couldn't infer template argument 'T'}} | ||
- int *p1 = f({1, 2, 3}); | + // since-cxx11-note@#dr1591-g-1 {{candidate template ignored: couldn't infer template argument 'T'}} | ||
+ // since-cxx11-note@#dr1591-g-3 {{candidate template ignored: deduced conflicting values for parameter 'O' (2 vs. 3)}} | |||
+ int **p2 = g({ {1,2,3}, {3, 4, 5} }); | |||
+ int **p22 = g({ {1,2}, {3, 4} }); | |||
+ int *p1 = g({1, 2, 3}); | |||
} | } | ||
namespace check_arrays_of_ | namespace check_arrays_of_ | ||
- template<class T, int N> float * | + template<class T, int N> float *h(const std::initializer_list<T> (&)[N]); | ||
- template<class T, int N> double * | + template<class T, int N> double *h(const T(&)[N]); | ||
- double *p = | + double *p = h({1, 2, 3}); | ||
- float *fp = | + float *fp = h({{1}, {1, 2}, {1, 2, 3}}); | ||
} | } | ||
namespace core_reflector_2 | namespace core_reflector_2 | ||
- template<class T, int N> int * | + template<class T, int N> int *i(T (&&)[N]); // #1 | ||
- template<class T> char * | + template<class T> char *i(std::initializer_list<T> &&); // #2 | ||
- template<class T, int N, int M> int ** | + template<class T, int N, int M> int **i(T (&&)[N][M]); // #3 #dr1591-i-2 | ||
- template<class T, int N> char ** | + template<class T, int N> char **i(std::initializer_list<T> (&&)[N]); // #4 #dr1591-i-1 | ||
- template<class T> short * | + template<class T> short *i(T (&&)[2]); // #5 | ||
template<class T> using Arr = T[]; | template<class T> using Arr = T[]; | ||
- char *pc = | + char *pc = i({1, 2, 3}); // OK prefer #2 via 13.3.3.2 [over.ics.rank] | ||
- char *pc2 = | + char *pc2 = i({1, 2}); // #2 also | ||
- int *pi = | + int *pi = i(Arr<int>{1, 2, 3}); // OK prefer #1 | ||
- void *pv1 = | + void *pv1 = i({ {1, 2, 3}, {4, 5, 6} }); // ambiguous btw 3 & 4 | ||
- char **pcc = f({ {1}, {2, 3} }); // OK #4 | + // since-cxx11-error@-1 {{call to 'i' is ambiguous}} | ||
+ // since-cxx11-note@#dr1591-i-2 {{candidate function [with T = int, N = 2, M = 3]}} | |||
+ // since-cxx11-note@#dr1591-i-1 {{candidate function [with T = int, N = 2]}} | |||
+ char **pcc = i({ {1}, {2, 3} }); // OK #4 | |||
- short *ps = | + short *ps = i(Arr<int>{1, 2}); // OK #5 | ||
} | } | ||
-} // dr1591 | |||
- | |||
#endif | #endif | ||
+} // dr1591 |
@@ -1,12 +1,14 @@ | |||
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++ | +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
- | +// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-#if __cplusplus < 201103L | +// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// expected-error@+1 {{variadic macro}} | + | ||
+#if __cplusplus == 199711L | |||
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) | #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) | ||
+// cxx98-error@-1 {{variadic macros are a C99 feature}} | |||
#endif | #endif | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
@@ -25,9 +27,7 @@ namespace std { | |||
namespace dr1601 { // dr1601: 10 | namespace dr1601 { // dr1601: 10 | ||
enum E : char { e }; | enum E : char { e }; | ||
-#if __cplusplus < 201103L | +// cxx98-error@-1 {{enumeration types with a fixed underlying type are a C++11 extension}} | ||
- // expected-error@-2 {{enumeration types with a fixed underlying type are a C++11 extension}} | |||
-#endif | |||
void f(char); | void f(char); | ||
void f(int); | void f(int); | ||
void g() { | void g() { | ||
@@ -53,26 +53,30 @@ namespace dr1631 { // dr1631: 3.7 | |||
void f(int, A); | void f(int, A); | ||
void test() { | void test() { | ||
- f({0}, {{1}}); | + f({0}, {{1}}); | ||
+ // since-cxx11-warning@-1 {{braces around scalar initializer}} | |||
} | } | ||
namespace with_error { | namespace with_error { | ||
void f(B, int); // TODO: expected- note {{candidate function}} | void f(B, int); // TODO: expected- note {{candidate function}} | ||
- void f(int, A); // | + void f(int, A); // #dr1631-f | ||
- void f(int, A, int = 0); // | + void f(int, A, int = 0); // #dr1631-f-int | ||
void test() { | void test() { | ||
- f({0}, {{1}}); | + f({0}, {{1}}); | ||
+ // since-cxx11-error@-1 {{call to 'f' is ambiguous}} | |||
+ // since-cxx11-note@#dr1631-f {{candidate function}} | |||
+ // since-cxx11-note@#dr1631-f-int {{candidate function}} | |||
} | } | ||
} | } | ||
#endif | #endif | ||
} | } | ||
-namespace dr1638 { // dr1638: | +namespace dr1638 { // dr1638: 3.1 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
template<typename T> struct A { | template<typename T> struct A { | ||
- enum class E; // | + enum class E; // #dr1638-E | ||
- enum class F : T; // | + enum class F : T; // #dr1638-F | ||
}; | }; | ||
template<> enum class A<int>::E; | template<> enum class A<int>::E; | ||
@@ -83,16 +87,27 @@ namespace dr1638 { // dr1638: yes | |||
template<> enum class A<short>::E : int; | template<> enum class A<short>::E : int; | ||
template<> enum class A<short>::E : int {}; | template<> enum class A<short>::E : int {}; | ||
- template<> enum class A<short>::F; | + template<> enum class A<short>::F; | ||
- template<> enum class A<char>::E : char; // expected-error {{different underlying type}} | + // since-cxx11-error@-1 {{enumeration redeclared with different underlying type 'int' (was 'short')}} | ||
- template<> enum class A<char>::F : int; // expected-error {{different underlying type}} | + // since-cxx11-note@#dr1638-F {{previous declaration is here}} | ||
- | + template<> enum class A<char>::E : char; | ||
- enum class A<unsigned>::E; // expected-error {{template specialization requires 'template<>'}} expected-error {{nested name specifier}} | + // since-cxx11-error@-1 {{enumeration redeclared with different underlying type 'char' (was 'int')}} | ||
- template enum class A<unsigned>::E; // expected-error {{enumerations cannot be explicitly instantiated}} | + // since-cxx11-note@#dr1638-E {{previous declaration is here}} | ||
- enum class A<unsigned>::E *e; // expected-error {{must use 'enum' not 'enum class'}} | + template<> enum class A<char>::F : int; | ||
+ // since-cxx11-error@-1 {{enumeration redeclared with different underlying type 'int' (was 'char')}} | |||
+ // since-cxx11-note@#dr1638-F {{previous declaration is here}} | |||
+ | |||
+ enum class A<unsigned>::E; | |||
+ // since-cxx11-error@-1 {{template specialization requires 'template<>'}} | |||
+ // since-cxx11-error@-2 {{forward declaration of enum class cannot have a nested name specifier}} | |||
+ template enum class A<unsigned>::E; | |||
+ // since-cxx11-error@-1 {{enumerations cannot be explicitly instantiated}} | |||
+ enum class A<unsigned>::E *e; | |||
+ // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}} | |||
struct B { | struct B { | ||
- friend enum class A<unsigned>::E; | + friend enum class A<unsigned>::E; | ||
+ // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}} | |||
}; | }; | ||
#endif | #endif | ||
} | } | ||
@@ -100,37 +115,50 @@ namespace dr1638 { // dr1638: yes | |||
namespace dr1645 { // dr1645: 3.9 | namespace dr1645 { // dr1645: 3.9 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
struct A { | struct A { | ||
- constexpr A(int, float = 0); // | + constexpr A(int, float = 0); // #dr1645-int-float | ||
- explicit A(int, int = 0); // | + explicit A(int, int = 0); // #dr1645-int-int | ||
- A(int, int, int = 0) = delete; // | + A(int, int, int = 0) = delete; // #dr1645-int-int-int | ||
}; | }; | ||
struct B : A { | struct B : A { | ||
- using A::A; // | + using A::A; // #dr1645-using | ||
}; | }; | ||
- constexpr B a(0); | + constexpr B a(0); | ||
- constexpr B b(0, 0); // expected-error {{ambiguous}} | + // since-cxx11-error@-1 {{call to constructor of 'const B' is ambiguous}} | ||
+ // since-cxx11-note@#dr1645-int-float {{candidate inherited constructor}} | |||
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}} | |||
+ // since-cxx11-note@#dr1645-int-int {{candidate inherited constructor}} | |||
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}} | |||
+ constexpr B b(0, 0); | |||
+ // since-cxx11-error@-1 {{call to constructor of 'const B' is ambiguous}} | |||
+ // since-cxx11-note@#dr1645-int-int {{candidate inherited constructor}} | |||
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}} | |||
+ // since-cxx11-note@#dr1645-int-int-int {{candidate inherited constructor has been explicitly deleted}} | |||
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}} | |||
#endif | #endif | ||
} | } | ||
namespace dr1652 { // dr1652: 3.6 | namespace dr1652 { // dr1652: 3.6 | ||
int a, b; | int a, b; | ||
- int arr[&a + 1 == &b ? 1 : 2]; | + int arr[&a + 1 == &b ? 1 : 2]; | ||
- // expected-note@-1 {{points past the end}} | + // expected-error@-1 {{variable length arrays in C++ are a Clang extension}} | ||
+ // expected-note@-2 {{comparison against pointer '&a + 1' that points past the end of a complete object has unspecified value}} | |||
+ // expected-error@-3 {{variable length array declaration not allowed at file scope}} | |||
} | } | ||
namespace dr1653 { // dr1653: 4 c++17 | namespace dr1653 { // dr1653: 4 c++17 | ||
void f(bool b) { | void f(bool b) { | ||
++b; | ++b; | ||
+ // cxx98-14-warning@-1 {{incrementing expression of type bool is deprecated and incompatible with C++17}} | |||
+ // since-cxx17-error@-2 {{SO C++17 does not allow incrementing expression of type bool}} | |||
b++; | b++; | ||
-#if __cplusplus <= 201402L | + // cxx98-14-warning@-1 {{incrementing expression of type bool is deprecated and incompatible with C++17}} | ||
- // expected-warning@-3 {{deprecated}} expected-warning@-2 {{deprecated}} | + // since-cxx17-error@-2 {{SO C++17 does not allow incrementing expression of type bool}} | ||
-#else | + --b; | ||
- // expected-error@-5 {{incrementing expression of type bool}} expected-error@-4 {{incrementing expression of type bool}} | + // expected-error@-1 {{cannot decrement expression of type bool}} | ||
-#endif | + b--; | ||
- | + // expected-error@-1 {{cannot decrement expression of type bool}} | ||
- b--; // expected-error {{cannot decrement expression of type bool}} | |||
b += 1; // ok | b += 1; // ok | ||
b -= 1; // ok | b -= 1; // ok | ||
} | } | ||
@@ -138,71 +166,88 @@ namespace dr1653 { // dr1653: 4 c++17 | |||
namespace dr1658 { // dr1658: 5 | namespace dr1658 { // dr1658: 5 | ||
namespace DefCtor { | namespace DefCtor { | ||
- class A { A(); }; // | + class A { A(); }; // #dr1658-A1 | ||
- class B { ~B(); }; // | + class B { ~B(); }; // #dr1658-B1 | ||
// The stars align! An abstract class does not construct its virtual bases. | // The stars align! An abstract class does not construct its virtual bases. | ||
struct C : virtual A { C(); virtual void foo() = 0; }; | struct C : virtual A { C(); virtual void foo() = 0; }; | ||
- C::C() = default; // ok, not deleted | + C::C() = default; // ok, not deleted | ||
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | |||
struct D : virtual B { D(); virtual void foo() = 0; }; | struct D : virtual B { D(); virtual void foo() = 0; }; | ||
- D::D() = default; // ok, not deleted | + D::D() = default; // ok, not deleted | ||
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | |||
// In all other cases, we are not so lucky. | // In all other cases, we are not so lucky. | ||
- struct E : A { E(); virtual void foo() = 0; }; | + struct E : A { E(); virtual void foo() = 0; }; // #dr1658-E1 | ||
-#if __cplusplus < 201103L | + E::E() = default; // #dr1658-E1-ctor | ||
- E::E() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}} | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
-#else | + // cxx98-error@-2 {{base class 'A' has private default constructor}} | ||
- E::E() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}} | + // cxx98-note@-3 {{in defaulted default constructor for 'dr1658::DefCtor::E' first required here}} | ||
-#endif | + // cxx98-note@#dr1658-A1 {{implicitly declared private here}} | ||
- struct F : virtual A { F(); }; | + // since-cxx11-error@#dr1658-E1-ctor {{defaulting this default constructor would delete it after its first declaration}} | ||
-#if __cplusplus < 201103L | + // since-cxx11-note@#dr1658-E1 {{default constructor of 'E' is implicitly deleted because base class 'A' has an inaccessible default constructor}} | ||
- F::F() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}} | + struct F : virtual A { F(); }; // #dr1658-F1 | ||
-#else | + F::F() = default; // #dr1658-F1-ctor | ||
- F::F() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}} | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
-#endif | + // cxx98-error@-2 {{inherited virtual base class 'A' has private default constructor}} | ||
- | + // cxx98-note@-3 {{in defaulted default constructor for 'dr1658::DefCtor::F' first required here}} | ||
- struct G : B { G(); virtual void foo() = 0; }; | + // cxx98-note@#dr1658-A1 {{implicitly declared private here}} | ||
-#if __cplusplus < 201103L | + // since-cxx11-error@#dr1658-F1-ctor {{defaulting this default constructor would delete it after its first declaration}} | ||
- G::G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}} | + // since-cxx11-note@#dr1658-F1 {{default constructor of 'F' is implicitly deleted because base class 'A' has an inaccessible default constructor}} | ||
-#else | + | ||
- G::G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}} | + struct G : B { G(); virtual void foo() = 0; }; // #dr1658-G1 | ||
-#endif | + G::G() = default; // #dr1658-G1-ctor | ||
- struct H : virtual B { H(); }; | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
-#if __cplusplus < 201103L | + // cxx98-error@#dr1658-G1 {{base class 'B' has private destructor}} | ||
- H::H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}} | + // cxx98-note@#dr1658-G1-ctor {{in defaulted default constructor for 'dr1658::DefCtor::G' first required here}} | ||
-#else | + // cxx98-note@#dr1658-B1 {{implicitly declared private here}} | ||
- H::H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}} | + // since-cxx11-error@#dr1658-G1-ctor {{defaulting this default constructor would delete it after its first declaration}} | ||
-#endif | + // since-cxx11-note@#dr1658-G1 {{default constructor of 'G' is implicitly deleted because base class 'B' has an inaccessible destructor}} | ||
+ struct H : virtual B { H(); }; // #dr1658-H1 | |||
+ H::H() = default; // #dr1658-H1-ctor | |||
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | |||
+ // cxx98-error@#dr1658-H1 {{base class 'B' has private destructor}} | |||
+ // cxx98-note@#dr1658-H1-ctor {{in defaulted default constructor for 'dr1658::DefCtor::H' first required here}} | |||
+ // cxx98-note@#dr1658-B1 {{implicitly declared private here}} | |||
+ // since-cxx11-error@#dr1658-H1-ctor {{defaulting this default constructor would delete it after its first declaration}} | |||
+ // since-cxx11-note@#dr1658-H1 {{default constructor of 'H' is implicitly deleted because base class 'B' has an inaccessible destructor}} | |||
} | } | ||
namespace Dtor { | namespace Dtor { | ||
- class B { ~B(); }; // | + class B { ~B(); }; // #dr1658-B2 | ||
struct D : virtual B { ~D(); virtual void foo() = 0; }; | struct D : virtual B { ~D(); virtual void foo() = 0; }; | ||
- D::~D() = default; // ok, not deleted | + D::~D() = default; // ok, not deleted | ||
- | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
- struct G : B { ~G(); virtual void foo() = 0; }; | + | ||
-#if __cplusplus < 201103L | + struct G : B { ~G(); virtual void foo() = 0; }; // #dr1658-G2 | ||
- G::~G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}} | + G::~G() = default; // #dr1658-G2-dtor | ||
-#else | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
- G::~G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}} | + // cxx98-error@#dr1658-G2 {{base class 'B' has private destructor}} | ||
-#endif | + // cxx98-note@#dr1658-G2-dtor {{in defaulted destructor for 'dr1658::Dtor::G' first required here}} | ||
- struct H : virtual B { ~H(); }; | + // cxx98-note@#dr1658-B2 {{implicitly declared private here}} | ||
-#if __cplusplus < 201103L | + // since-cxx11-error@#dr1658-G2-dtor {{defaulting this destructor would delete it after its first declaration}} | ||
- H::~H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}} | + // since-cxx11-note@#dr1658-G2 {{destructor of 'G' is implicitly deleted because base class 'B' has an inaccessible destructor}} | ||
-#else | + struct H : virtual B { ~H(); }; // #dr1658-H2 | ||
- H::~H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}} | + H::~H() = default; // #dr1658-H2-dtor | ||
-#endif | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
+ // cxx98-error@#dr1658-H2 {{base class 'B' has private destructor}} | |||
+ // cxx98-note@#dr1658-H2-dtor {{in defaulted destructor for 'dr1658::Dtor::H' first required here}} | |||
+ // cxx98-note@#dr1658-B2 {{implicitly declared private here}} | |||
+ // since-cxx11-error@#dr1658-H2-dtor {{defaulting this destructor would delete it after its first declaration}} | |||
+ // since-cxx11-note@#dr1658-H2 {{destructor of 'H' is implicitly deleted because base class 'B' has an inaccessible destructor}} | |||
} | } | ||
namespace MemInit { | namespace MemInit { | ||
- struct A { A(int); }; // | + struct A { A(int); }; // #dr1658-A3 | ||
struct B : virtual A { | struct B : virtual A { | ||
B() {} | B() {} | ||
virtual void f() = 0; | virtual void f() = 0; | ||
}; | }; | ||
struct C : virtual A { | struct C : virtual A { | ||
- C() {} | + C() {} | ||
+ // expected-error@-1 {{constructor for 'dr1658::MemInit::C' must explicitly initialize the base class 'A' which does not have a default constructor}} | |||
+ // expected-note@#dr1658-A3 {{'dr1658::MemInit::A' declared here}} | |||
}; | }; | ||
} | } | ||
@@ -220,28 +265,51 @@ namespace dr1658 { // dr1658: 5 | |||
} | } | ||
namespace CopyCtor { | namespace CopyCtor { | ||
- class A { A(const A&); A(A&&); }; // | + class A { A(const A&); A(A&&); }; // #dr1658-A5 | ||
- | + // cxx98-error@-1 {{rvalue references are a C++11 extension}} | ||
- struct C : virtual A { C(const C&); C(C&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}} | + | ||
- C::C(const C&) = default; // expected-error 0-1{{extension}} | + struct C : virtual A { C(const C&); C(C&&); virtual void foo() = 0; }; | ||
- C::C(C&&) = default; // expected-error 0-2{{extension}} | + // cxx98-error@-1 {{rvalue references are a C++11 extension}} | ||
- | + C::C(const C&) = default; | ||
- struct E : A { E(const E&); E(E&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}} | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
-#if __cplusplus < 201103L | + C::C(C&&) = default; | ||
- E::E(const E&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}} | + // cxx98-error@-1 {{rvalue references are a C++11 extension}} | ||
- E::E(E&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}} | + // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}} | ||
-#else | + | ||
- E::E(const E&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}} | + struct E : A { E(const E&); E(E&&); virtual void foo() = 0; }; // #dr1658-E5 | ||
- E::E(E&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}} | + // cxx98-error@-1 {{rvalue references are a C++11 extension}} | ||
-#endif | + E::E(const E&) = default; // #dr1658-E5-copy-ctor | ||
- struct F : virtual A { F(const F&); F(F&&); }; // expected-error 0-1{{extension}} | + // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | ||
-#if __cplusplus < 201103L | + // cxx98-error@-2 {{base class 'A' has private copy constructor}} | ||
- F::F(const F&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}} | + // cxx98-note@-3 {{in defaulted copy constructor for 'dr1658::CopyCtor::E' first required here}} | ||
- F::F(F&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}} | + // cxx98-note@#dr1658-A5 {{implicitly declared private here}} | ||
-#else | + // since-cxx11-error@#dr1658-E5-copy-ctor {{defaulting this copy constructor would delete it after its first declaration}} | ||
- F::F(const F&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}} | + // since-cxx11-note@#dr1658-E5 {{copy constructor of 'E' is implicitly deleted because base class 'A' has an inaccessible copy constructor}} | ||
- F::F(F&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}} | + E::E(E&&) = default; // #dr1658-E5-move-ctor | ||
-#endif | + // cxx98-error@-1 {{rvalue references are a C++11 extension}} | ||
+ // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}} | |||
+ // cxx98-error@-3 {{base class 'A' has private move constructor}} | |||
+ // cxx98-note@-4 {{in defaulted move constructor for 'dr1658::CopyCtor::E' first required here}} | |||
+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}} | |||
+ // since-cxx11-error@#dr1658-E5-move-ctor {{defaulting this move constructor would delete it after its first declaration}} | |||
+ // since-cxx11-note@#dr1658-E5 {{move constructor of 'E' is implicitly deleted because base class 'A' has an inaccessible move constructor}} | |||
+ struct F : virtual A { F(const F&); F(F&&); }; // #dr1658-F5 | |||
+ // cxx98-error@-1 {{rvalue references are a C++11 extension}} | |||
+ F::F(const F&) = default; // #dr1658-F5-copy-ctor | |||
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}} | |||
+ // cxx98-error@-2 {{inherited virtual base class 'A' has private copy constructor}} | |||
+ // cxx98-note@-3 {{in defaulted copy constructor for 'dr1658::CopyCtor::F' first required here}} | |||
+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}} | |||
+ // since-cxx11-error@#dr1658-F5-copy-ctor {{defaulting this copy constructor would delete it after its first declaration}} | |||
+ // since-cxx11-note@#dr1658-F5 {{copy constructor of 'F' is implicitly deleted because base class 'A' has an inaccessible copy constructor}} | |||
+ F::F(F&&) = default; // #dr1658-F5-move-ctor | |||
+ // cxx98-error@-1 {{rvalue references are a C++11 extension}} | |||
+ // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}} | |||
+ // cxx98-error@-3 {{inherited virtual base class 'A' has private move constructor}} | |||
+ // cxx98-note@-4 {{in defaulted move constructor for 'dr1658::CopyCtor::F' first required here}} | |||
+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}} | |||
+ // since-cxx11-error@#dr1658-F5-move-ctor {{defaulting this move constructor would delete it after its first declaration}} | |||
+ // since-cxx11-note@#dr1658-F5 {{move constructor of 'F' is implicitly deleted because base class 'A' has an inaccessible move constructor}} | |||
} | } | ||
// assignment case is superseded by dr2180 | // assignment case is superseded by dr2180 | ||
@@ -274,31 +342,38 @@ namespace dr1672 { // dr1672: 7 | |||
namespace dr1684 { // dr1684: 3.6 | namespace dr1684 { // dr1684: 3.6 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- struct NonLiteral { // | + struct NonLiteral { // #dr1684-struct | ||
NonLiteral(); | NonLiteral(); | ||
- constexpr int f() { return 0; } | + constexpr int f() { return 0; } | ||
+ // cxx11-warning@-1 {{'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior}} | |||
}; | }; | ||
constexpr int f(NonLiteral &) { return 0; } | constexpr int f(NonLiteral &) { return 0; } | ||
- constexpr int f(NonLiteral) { return 0; } | + constexpr int f(NonLiteral) { return 0; } | ||
+ // since-cxx11-error@-1 {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} | |||
+ // since-cxx11-note@#dr1684-struct {{'NonLiteral' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} | |||
#endif | #endif | ||
} | } | ||
namespace dr1687 { // dr1687: 7 | namespace dr1687 { // dr1687: 7 | ||
template<typename T> struct To { | template<typename T> struct To { | ||
- operator T(); // expected-note 2{{first operand was implicitly converted to type 'int *'}} | + operator T(); // #dr1687-op-T | ||
- // expected-note@-1 {{second operand was implicitly converted to type 'double'}} | |||
-#if __cplusplus > 201703L | |||
- // expected-note@-3 2{{operand was implicitly converted to type 'dr1687::E}} | |||
-#endif | |||
}; | }; | ||
- int *a = To<int*>() + 100.0; // expected-error {{invalid operands to binary expression ('To<int *>' and 'double')}} | + int *a = To<int*>() + 100.0; | ||
- | + // expected-error@-1 {{invalid operands to binary expression ('To<int *>' and 'double')}} | ||
+ // expected-note@#dr1687-op-T {{first operand was implicitly converted to type 'int *'}} | |||
+ // since-cxx20-note@#dr1687-op-T {{second operand was implicitly converted to type 'dr1687::E2'}} | |||
+ int *b = To<int*>() + To<double>(); | |||
+ // expected-error@-1 {{invalid operands to binary expression ('To<int *>' and 'To<double>')}} | |||
+ // expected-note@#dr1687-op-T {{first operand was implicitly converted to type 'int *'}} | |||
+ // expected-note@#dr1687-op-T {{second operand was implicitly converted to type 'double'}} | |||
-#if __cplusplus | +#if __cplusplus >= 202002L | ||
enum E1 {}; | enum E1 {}; | ||
enum E2 {}; | enum E2 {}; | ||
- auto c = To<E1>() <=> To<E2>(); | + auto c = To<E1>() <=> To<E2>(); | ||
+ // since-cxx20-error@-1 {{invalid operands to binary expression ('To<E1>' and 'To<E2>')}} | |||
+ // since-cxx20-note@#dr1687-op-T {{operand was implicitly converted to type 'dr1687::E}} | |||
#endif | #endif | ||
} | } | ||
@@ -325,12 +400,14 @@ namespace dr1691 { // dr1691: 9 | |||
void f(E); | void f(E); | ||
} | } | ||
enum M::E : int {}; | enum M::E : int {}; | ||
- void g(M::E); // | + void g(M::E); // #dr1691-g | ||
} | } | ||
void test() { | void test() { | ||
N::M::E e; | N::M::E e; | ||
f(e); // ok | f(e); // ok | ||
- g(e); // expected-error {{use of undeclared}} | + g(e); | ||
+ // since-cxx11-error@-1 {{use of undeclared identifier 'g'; did you mean 'N::g'?}} | |||
+ // since-cxx11-note@#dr1691-g {{'N::g' declared here}} | |||
} | } | ||
#endif | #endif | ||
} | } | ||
@@ -356,7 +433,9 @@ namespace dr1696 { // dr1696: 7 | |||
extern struct A a; | extern struct A a; | ||
struct A { | struct A { | ||
const A &x = { A{a, a} }; | const A &x = { A{a, a} }; | ||
- const A &y = { A{} }; | + const A &y = { A{} }; | ||
+ // since-cxx14-error@-1 {{default member initializer for 'y' needed within definition of enclosing class 'A' outside of member functions}} | |||
+ // since-cxx14-note@-2 {{default member initializer declared here}} | |||
}; | }; | ||
A a{a, a}; | A a{a, a}; | ||
#endif | #endif | ||
@@ -365,16 +444,20 @@ namespace dr1696 { // dr1696: 7 | |||
struct A { A(); ~A(); }; | struct A { A(); ~A(); }; | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
struct B { | struct B { | ||
- A &&a; // expected-note {{declared here}} | + A &&a; // #dr1696-a | ||
- B() : a{} {} // expected-error {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | + B() : a{} {} | ||
+ // since-cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | |||
+ // since-cxx11-note@#dr1696-a {{reference member declared here}} | |||
} b; | } b; | ||
#endif | #endif | ||
struct C { | struct C { | ||
C(); | C(); | ||
- const A &a; // | + const A &a; // #dr1696-C-a | ||
}; | }; | ||
- C::C() : a(A()) {} // expected-error {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | + C::C() : a(A()) {} | ||
+ // expected-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | |||
+ // expected-note@#dr1696-C-a {{reference member declared here}} | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
// This is OK in C++14 onwards, per DR1815, though we don't support that yet: | // This is OK in C++14 onwards, per DR1815, though we don't support that yet: | ||
@@ -383,51 +466,62 @@ namespace dr1696 { // dr1696: 7 | |||
// D1 d1 = {A()}; | // D1 d1 = {A()}; | ||
// ... which lifetime-extends the A temporary. | // ... which lifetime-extends the A temporary. | ||
struct D1 { | struct D1 { | ||
-#if __cplusplus < 201402L | + // cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | ||
- // expected-error@-2 {{binds to a temporary}} | + // cxx11-note@#dr1696-d1 {{in implicit default constructor for 'dr1696::D1' first required here}} | ||
-#endif | + // cxx11-note@#dr1696-D1-a {{initializing field 'a' with default member initializer}} | ||
- const A &a = A(); // | + const A &a = A(); // #dr1696-D1-a | ||
}; | }; | ||
- D1 d1 = {}; | + D1 d1 = {}; // #dr1696-d1 | ||
-#if __cplusplus < 201402L | + // since-cxx14-warning@-1 {{sorry, lifetime extension of temporary created by aggregate initialization using default member initializer is not supported; lifetime of temporary will end at the end of the full-expression}} | ||
- // expected-note@-2 {{first required here}} | + // since-cxx14-note@#dr1696-D1-a {{initializing field 'a' with default member initializer}} | ||
-#else | |||
- // expected-warning-re@-4 {{sorry, lifetime extension {{.*}} not supported}} | |||
-#endif | |||
struct D2 { | struct D2 { | ||
- const A &a = A(); // | + const A &a = A(); // #dr1696-D2-a | ||
- D2() {} | + D2() {} | ||
+ // since-cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | |||
+ // since-cxx11-note@#dr1696-D2-a {{initializing field 'a' with default member initializer}} | |||
}; | }; | ||
- struct D3 { | + struct D3 { | ||
- const A &a = A(); // expected-note {{default member init}} | + // since-cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | ||
+ // since-cxx11-note@#dr1696-d3 {{in implicit default constructor for 'dr1696::D3' first required here}} | |||
+ // since-cxx11-note@#dr1696-D3-a {{initializing field 'a' with default member initializer}} | |||
+ const A &a = A(); // #dr1696-D3-a | |||
}; | }; | ||
- D3 d3; // expected-note {{first required here}} | + D3 d3; // #dr1696-d3 | ||
struct haslist1 { | struct haslist1 { | ||
- std::initializer_list<int> il; // | + std::initializer_list<int> il; // #dr1696-il-1 | ||
- haslist1(int i) : il{i, 2, 3} {} | + haslist1(int i) : il{i, 2, 3} {} | ||
+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list | |||
+ // since-cxx11-note@#dr1696-il-1 {{'std::initializer_list | |||
}; | }; | ||
struct haslist2 { | struct haslist2 { | ||
- std::initializer_list<int> il; // | + std::initializer_list<int> il; // #dr1696-il-2 | ||
haslist2(); | haslist2(); | ||
}; | }; | ||
- haslist2::haslist2() : il{1, 2} {} | + haslist2::haslist2() : il{1, 2} {} | ||
+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list | |||
+ // since-cxx11-note@#dr1696-il-2 {{'std::initializer_list | |||
struct haslist3 { | struct haslist3 { | ||
std::initializer_list | std::initializer_list | ||
}; | }; | ||
- struct haslist4 { | + struct haslist4 { | ||
- std::initializer_list | + // since-cxx11-error@-1 {{backing array for 'std::initializer_list | ||
+ // since-cxx11-note@#dr1696-hl4 {{in implicit default constructor for 'dr1696::haslist4' first required here}} | |||
+ // since-cxx11-note@#dr1696-il-4 {{initializing field 'il' with default member initializer}} | |||
+ std::initializer_list | |||
}; | }; | ||
- haslist4 hl4; // expected-note {{in implicit default constructor}} | + haslist4 hl4; // #dr1696-hl4 | ||
struct haslist5 { | struct haslist5 { | ||
- std::initializer_list<int> il = {1, 2, 3}; // | + std::initializer_list<int> il = {1, 2, 3}; // #dr1696-il-5 | ||
- haslist5() {} // expected-error {{backing array for 'std::initializer_list | + haslist5() {} | ||
+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list | |||
+ // since-cxx11-note@#dr1696-il-5 {{nitializing field 'il' with default member initializer}} | |||
}; | }; | ||
#endif | #endif | ||
} | } |
@@ -1,10 +1,10 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++20 %s - | +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++23 %s - | +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++2c %s - | +// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
namespace dr1710 { // dr1710: no | namespace dr1710 { // dr1710: no | ||
// FIXME: all of the following is well-formed | // FIXME: all of the following is well-formed | ||
@@ -32,13 +32,17 @@ namespace dr1715 { // dr1715: 3.9 | |||
struct D : B { | struct D : B { | ||
using B::B; | using B::B; | ||
}; | }; | ||
- struct E : B { // | + struct E : B { // #dr1715-E | ||
- template<class T> E(T t, typename T::Q q) : B(t, q) {} // | + template<class T> E(T t, typename T::Q q) : B(t, q) {} // #dr1715-E-ctor | ||
}; | }; | ||
B b(S(), 1); | B b(S(), 1); | ||
D d(S(), 2); | D d(S(), 2); | ||
- E e(S(), 3); | + E e(S(), 3); | ||
+ // since-cxx11-error@-1 {{no matching constructor for initialization of 'E'}} | |||
+ // since-cxx11-note@#dr1715-E-ctor {{candidate template ignored: substitution failure [with T = S]: 'Q' is a private member of 'dr1715::S'}} | |||
+ // since-cxx11-note@#dr1715-E {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}} | |||
+ // since-cxx11-note@#dr1715-E {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}} | |||
#endif | #endif | ||
} | } | ||
@@ -73,12 +77,15 @@ struct S { | |||
struct L : S { | struct L : S { | ||
using S::S; | using S::S; | ||
}; | }; | ||
- typename T::type value; | + typename T::type value; | ||
- L l(value); // expected-note {{instantiation of}} | + // since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}} | ||
+ // since-cxx11-note@#dr1736-l {{in instantiation of function template specialization 'dr1736::S::S<int>' requested here}} | |||
+ // since-cxx11-note@#dr1736-s {{in instantiation of function template specialization 'dr1736::S::S<dr1736::Q>' requested here}} | |||
+ L l(value); // #dr1736-l | |||
} | } | ||
}; | }; | ||
struct Q { typedef int type; } q; | struct Q { typedef int type; } q; | ||
-S s(q); // expected-note {{instantiation of}} | +S s(q); // #dr1736-s | ||
#endif | #endif | ||
} | } | ||
@@ -91,18 +98,23 @@ namespace dr1753 { // dr1753: 11 | |||
n.~T(); | n.~T(); | ||
n.T::~T(); | n.T::~T(); | ||
- n.dr1753::~T(); | + n.dr1753::~T(); | ||
+ // expected-error@-1 {{'dr1753' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T' (aka 'int')}} | |||
n.dr1753::T::~T(); | n.dr1753::T::~T(); | ||
- n.A::~T(); // expected-error {{the type of object expression ('T' (aka 'int')) does not match the type being destroyed ('A') in pseudo-destructor expression}} | + n.A::~T(); | ||
+ // expected-error@-1 {{the type of object expression ('T' (aka 'int')) does not match the type being destroyed ('A') in pseudo-destructor expression}} | |||
n.A::T::~T(); | n.A::T::~T(); | ||
- n.B::~T(); // expected-error {{'B' does not refer to a type name in pseudo-destructor expression}} | + n.B::~T(); | ||
+ // expected-error@-1 {{'B' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T' (aka 'int')}} | |||
n.B::T::~T(); | n.B::T::~T(); | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- n.decltype(n)::~T(); | + n.decltype(n)::~T(); | ||
- n.T::~decltype(n)(); // expected-error {{expected a class name after '~'}} | + // since-cxx11-error@-1 {{'decltype(n)' (aka 'int') is not a class, namespace, or enumeration}} | ||
+ n.T::~decltype(n)(); | |||
+ // since-cxx11-error@-1 {{expected a class name after '~' to name a destructor}} | |||
n.~decltype(n)(); // OK | n.~decltype(n)(); // OK | ||
#endif | #endif | ||
} | } | ||
@@ -141,9 +153,9 @@ namespace dr1758 { // dr1758: 3.7 | |||
namespace dr1762 { // dr1762: 14 | namespace dr1762 { // dr1762: 14 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
float operator ""_E(const char *); | float operator ""_E(const char *); | ||
- // expected-error@+2 {{invalid suffix on literal; C++11 requires a space between literal and identifier}} | |||
- // expected-warning@+1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}} | |||
float operator ""E(const char *); | float operator ""E(const char *); | ||
+ // since-cxx11-error@-1 {{invalid suffix on literal; C++11 requires a space between literal and identifier}} | |||
+ // since-cxx11-warning@-2 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}} | |||
#endif | #endif | ||
} | } | ||
@@ -1,14 +1,14 @@ | |||
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-17,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors | ||
- | + | ||
-#if __cplusplus | +#if __cplusplus == 199711L | ||
-// expected-error@+1 {{variadic macro}} | |||
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) | #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) | ||
+// cxx98-error@-1 {{variadic macros are a C99 feature}} | |||
#endif | #endif | ||
namespace dr1812 { // dr1812: no | namespace dr1812 { // dr1812: no | ||
@@ -16,7 +16,7 @@ namespace dr1812 { // dr1812: no | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
template <typename T> struct A { | template <typename T> struct A { | ||
using B = typename T::C<int>; | using B = typename T::C<int>; | ||
- // | + // since-cxx11-error@-1 {{use 'template' keyword to treat 'C' as a dependent template name}} | ||
}; | }; | ||
#endif | #endif | ||
} // namespace dr1812 | } // namespace dr1812 | ||
@@ -54,15 +54,20 @@ namespace dr1814 { // dr1814: yes | |||
namespace dr1815 { // dr1815: no | namespace dr1815 { // dr1815: no | ||
#if __cplusplus >= 201402L | #if __cplusplus >= 201402L | ||
// FIXME: needs codegen test | // FIXME: needs codegen test | ||
- struct A { int &&r = 0; }; // | + struct A { int &&r = 0; }; // #dr1815-A | ||
- A a = {}; | + A a = {}; | ||
- | + // since-cxx14-warning@-1 {{sorry, lifetime extension of temporary created by aggregate initialization using default member initializer is not supported; lifetime of temporary will end at the end of the full-expression}} FIXME | ||
- struct B { int &&r = 0; }; // expected-error {{binds to a temporary}} expected-note {{default member init}} | + // since-cxx14-note@#dr1815-A {{initializing field 'r' with default member initializer}} | ||
- B b; // expected-note {{here}} | + | ||
+ struct B { int &&r = 0; }; // #dr1815-B | |||
+ // since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} | |||
+ // since-cxx14-note@#dr1815-B {{initializing field 'r' with default member initializer}} | |||
+ // since-cxx14-note@#dr1815-b {{in implicit default constructor for 'dr1815::B' first required here}} | |||
+ B b; // #dr1815-b | |||
#endif | #endif | ||
} | } | ||
-namespace dr1821 { // dr1821: | +namespace dr1821 { // dr1821: 2.9 | ||
struct A { | struct A { | ||
template <typename> struct B { | template <typename> struct B { | ||
void f(); | void f(); | ||
@@ -80,9 +85,9 @@ struct A { | |||
namespace dr1822 { // dr1822: yes | namespace dr1822 { // dr1822: yes | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- int a; | + double a; | ||
auto x = [] (int a) { | auto x = [] (int a) { | ||
-#pragma clang __debug dump a // CHECK: ParmVarDecl | + static_assert(__is_same(decltype(a), int), "should be resolved to lambda parameter"); | ||
}; | }; | ||
#endif | #endif | ||
} | } | ||
@@ -98,16 +103,22 @@ namespace dr1837 { // dr1837: 3.3 | |||
}; | }; | ||
class Outer { | class Outer { | ||
- friend auto Other::q() -> decltype(this->p()) *; | + friend auto Other::q() -> decltype(this->p()) *; | ||
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}} | |||
int g(); | int g(); | ||
int f() { | int f() { | ||
extern void f(decltype(this->g()) *); | extern void f(decltype(this->g()) *); | ||
struct Inner { | struct Inner { | ||
- static_assert(Fish<decltype(this->g())>::value, ""); | + static_assert(Fish<decltype(this->g())>::value, ""); | ||
- enum { X = Fish<decltype(this->f())>::value }; // expected-error {{invalid use of 'this'}} | + // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}} | ||
- struct Inner2 : Fish<decltype(this->g())> { }; // expected-error {{invalid use of 'this'}} | + enum { X = Fish<decltype(this->f())>::value }; | ||
- friend void f(decltype(this->g()) *); // expected-error {{invalid use of 'this'}} | + // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}} | ||
- friend auto Other::q() -> decltype(this->p()) *; // expected-error {{invalid use of 'this'}} | + struct Inner2 : Fish<decltype(this->g())> { }; | ||
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}} | |||
+ friend void f(decltype(this->g()) *); | |||
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}} | |||
+ friend auto Other::q() -> decltype(this->p()) *; | |||
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}} | |||
}; | }; | ||
return 0; | return 0; | ||
} | } | ||
@@ -135,19 +146,21 @@ namespace dr1872 { // dr1872: 9 | |||
constexpr int x = A<X>().f(); | constexpr int x = A<X>().f(); | ||
constexpr int y = A<Y>().f(); | constexpr int y = A<Y>().f(); | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{constexpr variable 'y' must be initialized by a constant expression}} | ||
- // expected-error@-2 {{constant expression}} expected-note@-2 {{call to virtual function}} | + // cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}} | ||
-#else | +#if __cplusplus >= 202002L | ||
static_assert(y == 0); | static_assert(y == 0); | ||
#endif | #endif | ||
// Note, this is invalid even though it would not use virtual dispatch. | // Note, this is invalid even though it would not use virtual dispatch. | ||
constexpr int y2 = A<Y>().A<Y>::f(); | constexpr int y2 = A<Y>().A<Y>::f(); | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{constexpr variable 'y2' must be initialized by a constant expression}} | ||
- // expected-error@-2 {{constant expression}} expected-note@-2 {{call to virtual function}} | + // cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}} | ||
-#else | +#if __cplusplus >= 202002L | ||
static_assert(y == 0); | static_assert(y == 0); | ||
#endif | #endif | ||
- constexpr int z = A<Z>().f(); | + constexpr int z = A<Z>().f(); | ||
+ // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a constant expression}} | |||
+ // since-cxx11-note@-2 {{non-literal type 'A<Z>' cannot be used in a constant expression}} | |||
#endif | #endif | ||
} | } | ||
@@ -166,33 +179,38 @@ namespace dr1881 { // dr1881: 7 | |||
void dr1891() { // dr1891: 4 | void dr1891() { // dr1891: 4 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
int n; | int n; | ||
- auto a = []{}; // | + auto a = []{}; // #dr1891-a | ||
- auto b = [=]{ return n; }; // | + auto b = [=]{ return n; }; // #dr1891-b | ||
typedef decltype(a) A; | typedef decltype(a) A; | ||
typedef decltype(b) B; | typedef decltype(b) B; | ||
static_assert(!__has_trivial_co | static_assert(!__has_trivial_co | ||
-#if __cplusplus > 201703L | + // since-cxx20-error@-1 {{failed}} | ||
- // expected-error@-2 {{failed}} | |||
-#endif | |||
static_assert(!__has_trivial_co | static_assert(!__has_trivial_co | ||
// C++20 allows default construction for non-capturing lambdas (P0624R2). | // C++20 allows default construction for non-capturing lambdas (P0624R2). | ||
A x; | A x; | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error@-1 {{no matching constructor for initialization of 'A' (aka '(lambda at}} | ||
- // expected-error@-2 {{no matching constructor}} | + // cxx11-17-note@#dr1891-a {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} | ||
-#endif | + // cxx11-17-note@#dr1891-a {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} | ||
- B y; // expected-error {{no matching constructor}} | + B y; | ||
+ // since-cxx11-error@-1 {{no matching constructor for initialization of 'B' (aka '(lambda at}} | |||
+ // since-cxx11-note@#dr1891-b {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} | |||
+ // since-cxx11-note@#dr1891-b {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} | |||
// C++20 allows assignment for non-capturing lambdas (P0624R2). | // C++20 allows assignment for non-capturing lambdas (P0624R2). | ||
a = a; | a = a; | ||
+ // cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}} | |||
+ // cxx11-17-note@#dr1891-a {{lambda expression begins here}} | |||
a = static_cast<A&&>(a); | a = static_cast<A&&>(a); | ||
-#if __cplusplus <= 201703L | + // cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}} | ||
- // expected-error@-3 {{copy assignment operator is implicitly deleted}} | + // cxx11-17-note@#dr1891-a {{lambda expression begins here}} | ||
- // expected-error@-3 {{copy assignment operator is implicitly deleted}} | + b = b; | ||
-#endif | + // since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}} | ||
- b = b; // expected-error {{copy assignment operator is implicitly deleted}} | + // since-cxx11-note@#dr1891-b {{lambda expression begins here}} | ||
- b = static_cast<B&&>(b); | + b = static_cast<B&&>(b); | ||
+ // since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}} | |||
+ // since-cxx11-note@#dr1891-b {{lambda expression begins here}} | |||
#endif | #endif | ||
} | } | ||
@@ -1,41 +1,36 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-11,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++ | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | |||
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | |||
namespace std { struct type_info; } | namespace std { struct type_info; } | ||
namespace dr1902 { // dr1902: 3.7 | namespace dr1902 { // dr1902: 3.7 | ||
struct A {}; | struct A {}; | ||
struct B { | struct B { | ||
- B(A); | + B(A); // #dr1902-B-A | ||
-#if __cplusplus >= 201103L | + B() = delete; // #dr1902-B-ctor | ||
- // expected-note@-2 {{candidate}} | + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} | ||
-#endif | + B(const B&) = delete; // #dr1902-B-copy-ctor | ||
- | + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} | ||
- B() = delete; | |||
-#if __cplusplus < 201103L | |||
- // expected-error@-2 {{extension}} | |||
-#endif | |||
- | |||
- B(const B&) // expected-note {{deleted here}} | |||
-#if __cplusplus >= 201103L | |||
- // expected-note@-2 {{candidate}} | |||
-#else | |||
- // expected-error@+2 {{extension}} | |||
-#endif | |||
- = delete; | |||
- | |||
operator A(); | operator A(); | ||
}; | }; | ||
extern B b1; | extern B b1; | ||
- B b2(b1); | + B b2(b1); | ||
+ // expected-error@-1 {{call to deleted constructor of 'B'}} | |||
+ // expected-note@#dr1902-B-copy-ctor {{'B' has been explicitly marked deleted here}} | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
// This is ambiguous, even though calling the B(const B&) constructor would | // This is ambiguous, even though calling the B(const B&) constructor would | ||
// both directly and indirectly call a deleted function. | // both directly and indirectly call a deleted function. | ||
- B b({}); | + B b({}); | ||
+ // since-cxx11-error@-1 {{call to constructor of 'B' is ambiguous}} | |||
+ // since-cxx11-note@#dr1902-B-A {{candidate constructor}} | |||
+ // since-cxx11-note@#dr1902-B-copy-ctor {{candidate constructor has been explicitly deleted}} | |||
#endif | #endif | ||
} | } | ||
@@ -64,26 +59,33 @@ namespace dr1903 { | |||
} | } | ||
} | } | ||
-namespace dr1909 { // dr1909: | +namespace dr1909 { // dr1909: 3.7 | ||
struct A { | struct A { | ||
- template<typename T> struct A {}; | + template<typename T> struct A {}; | ||
+ // expected-error@-1 {{member 'A' has the same name as its class}} | |||
}; | }; | ||
struct B { | struct B { | ||
- template<typename T> void B() {} | + template<typename T> void B() {} | ||
+ // expected-error@-1 {{constructor cannot have a return type}} | |||
}; | }; | ||
struct C { | struct C { | ||
- template<typename T> static int C; | + template<typename T> static int C; | ||
+ // expected-error@-1 {{member 'C' has the same name as its class}} | |||
+ // cxx98-11-error@-2 {{variable templates are a C++14 extension}} | |||
}; | }; | ||
struct D { | struct D { | ||
- template<typename T> using D = int; | + template<typename T> using D = int; | ||
+ // cxx98-error@-1 {{alias declarations are a C++11 extension}} | |||
+ // expected-error@-2 {{member 'D' has the same name as its class}} | |||
}; | }; | ||
} | } | ||
-namespace dr1940 { // dr1940: | +namespace dr1940 { // dr1940: 3.5 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
static union { | static union { | ||
static_assert(true, ""); // ok | static_assert(true, ""); // ok | ||
- static_assert(false, ""); | + static_assert(false, ""); | ||
+ // since-cxx11-error@-1 {{static assertion failed}} | |||
int not_empty; | int not_empty; | ||
}; | }; | ||
#endif | #endif | ||
@@ -119,18 +121,21 @@ derived d2(42, 9); | |||
#endif | #endif | ||
} | } | ||
-namespace dr1947 { // dr1947: | +namespace dr1947 { // dr1947: 3.5 | ||
#if __cplusplus >= 201402L | #if __cplusplus >= 201402L | ||
unsigned o = 0'01; // ok | unsigned o = 0'01; // ok | ||
-unsigned b = 0b'01; | +unsigned b = 0b'01; | ||
-unsigned x = 0x'01; // expected-error {{invalid suffix 'x'01' on integer constant}} | +// since-cxx14-error@-1 {{invalid digit 'b' in octal constant}} | ||
+unsigned x = 0x'01; | |||
+// since-cxx14-error@-1 {{invalid suffix 'x'01' on integer constant}} | |||
#endif | #endif | ||
} | } | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
-// dr1948: | +// dr1948: 3.5 | ||
// FIXME: This diagnostic could be improved. | // FIXME: This diagnostic could be improved. | ||
-void *operator new(__SIZE_TYPE__) noexcept { return nullptr; } | +void *operator new(__SIZE_TYPE__) noexcept { return nullptr; } | ||
+// since-cxx11-error@-1 {{exception specification in declaration does not match previous declaration}} | |||
#endif | #endif | ||
namespace dr1959 { // dr1959: 3.9 | namespace dr1959 { // dr1959: 3.9 | ||
@@ -139,22 +144,31 @@ namespace dr1959 { // dr1959: 3.9 | |||
struct c; | struct c; | ||
struct a { | struct a { | ||
a() = default; | a() = default; | ||
- a(const a &) = delete; // | + a(const a &) = delete; // #dr1959-copy-ctor | ||
a(const b &) = delete; // not inherited | a(const b &) = delete; // not inherited | ||
- a(c &&) = delete; // | + a(c &&) = delete; // #dr1959-move-ctor | ||
- template<typename T> a(T) = delete; // | + template<typename T> a(T) = delete; // #dr1959-temp-ctor | ||
}; | }; | ||
- struct b : a { // expected-note {{cannot bind}} expected-note {{deleted because}} | + struct b : a { // #dr1959-b | ||
- using a::a; // expected-note 2{{inherited here}} | + using a::a; // #dr1959-using-a | ||
}; | }; | ||
a x; | a x; | ||
// FIXME: As a resolution to an open DR against P0136R0, we disallow | // FIXME: As a resolution to an open DR against P0136R0, we disallow | ||
// use of inherited constructors to construct from a single argument | // use of inherited constructors to construct from a single argument | ||
// where the base class is reference-related to the argument type. | // where the base class is reference-related to the argument type. | ||
- b y = x; // expected-error {{no viable conversion}} | + b y = x; | ||
- b z = z; // expected-error {{deleted}} | + // since-cxx11-error@-1 {{no viable conversion from 'a' to 'b'}} | ||
+ // since-cxx11-note@#dr1959-move-ctor {{candidate inherited constructor not viable: no known conversion from 'a' to 'c &&' for 1st argument}} | |||
+ // since-cxx11-note@#dr1959-using-a {{constructor from base class 'a' inherited here}} | |||
+ // since-cxx11-note@#dr1959-b {{candidate constructor (the implicit copy constructor) not viable: cannot bind base class object of type 'a' to derived class reference 'const b &' for 1st argument}} | |||
+ // since-cxx11-note@#dr1959-temp-ctor {{candidate template ignored: instantiation would take its own class type by value}} | |||
+ // since-cxx11-note@#dr1959-using-a {{constructor from base class 'a' inherited here}} | |||
+ b z = z; | |||
+ // since-cxx11-error@-1 {{call to implicitly-deleted copy constructor of 'b'}} | |||
+ // since-cxx11-note@#dr1959-b {{copy constructor of 'b' is implicitly deleted because base class 'a' has a deleted copy constructor}} | |||
+ // since-cxx11-note@#dr1959-copy-ctor {{'a' has been explicitly marked deleted here}} | |||
struct c : a { | struct c : a { | ||
using a::a; | using a::a; | ||
@@ -191,16 +205,28 @@ using A::g; | |||
namespace dr1966 { // dr1966: 11 | namespace dr1966 { // dr1966: 11 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
struct A { | struct A { | ||
- enum E : int {1}; | + enum E : int {1}; | ||
+ // since-cxx11-error@-1 {{expected identifier}} (not bit-field) | |||
}; | }; | ||
- auto *p1 = new enum E : int; | + auto *p1 = new enum E : int; | ||
- auto *p2 = new enum F : int {}; // expected-error {{only permitted as a standalone declaration}} | + // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}} | ||
- auto *p3 = true ? new enum G : int {}; // expected-error {{forward reference}} expected-error {{incomplete}} expected-note {{declaration}} | + auto *p2 = new enum F : int {}; | ||
- auto h() -> enum E : int {}; // expected-error {{only permitted as a standalone declaration}} | + // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}} | ||
- | + auto *p3 = true ? new enum G : int {}; | ||
- enum X : enum Y : int {} {}; // expected-error {{cannot be defined in a type specifier}} | + // since-cxx11-error@-1 {{ISO C++ forbids forward references to 'enum' types}} | ||
+ // since-cxx11-error@-2 {{allocation of incomplete type 'enum G'}} | |||
+ // since-cxx11-note@-3 {{forward declaration of 'dr1966::G'}} | |||
+ auto h() -> enum E : int {}; | |||
+ // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}} | |||
+ | |||
+ enum X : enum Y : int {} {}; | |||
+ // since-cxx11-error@-1 {{'dr1966::Y' cannot be defined in a type specifier}} | |||
struct Q { | struct Q { | ||
- enum X : enum Y : int {} {}; // expected-error +{{}} | + // FIXME: can we emit something nicer than that? | ||
+ enum X : enum Y : int {} {}; | |||
+ // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}} | |||
+ // since-cxx11-error@-2 {{non-integral type 'enum Y' is an invalid underlying type}} | |||
+ // since-cxx11-error@-3 {{anonymous bit-field cannot have a default member initializer}} | |||
}; | }; | ||
#endif | #endif | ||
} | } |
@@ -10,7 +10,7 @@ | |||
// expected-no-diagnostics | // expected-no-diagnostics | ||
#endif | #endif | ||
-namespace dr2516 { // dr2516: | +namespace dr2516 { // dr2516: 3.0 | ||
// NB: reusing 1482 test | // NB: reusing 1482 test | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
template <typename T> struct S { | template <typename T> struct S { |
@@ -1,9 +1,12 @@ | |||
// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)" | // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)" | ||
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | ||
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | ||
-// RUN: %clang_cc1 -std=c++ | +// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | ||
+// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | |||
+// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | |||
+// RUN: %clang_cc1 -std=c++2c %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= | |||
-// dr412: | +// dr412: 3.4 | ||
// lwg404: yes | // lwg404: yes | ||
// lwg2340: yes | // lwg2340: yes | ||
@@ -11,11 +14,17 @@ | |||
__extension__ typedef __SIZE_TYPE__ size_t; | __extension__ typedef __SIZE_TYPE__ size_t; | ||
namespace std { struct bad_alloc {}; } | namespace std { struct bad_alloc {}; } | ||
-inline void* operator new(size_t) BAD_ALLOC; | +inline void* operator new(size_t) BAD_ALLOC; | ||
- | +// expected-error@-1 {{replacement function 'operator new' cannot be declared 'inline'}} | ||
-inline void operator delete(void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} | +inline void* operator new[](size_t) BAD_ALLOC; | ||
- | +// expected-error@-1 {{replacement function 'operator new[]' cannot be declared 'inline'}} | ||
+inline void operator delete(void*) NOEXCEPT; | |||
+// expected-error@-1 {{replacement function 'operator delete' cannot be declared 'inline'}} | |||
+inline void operator delete[](void*) NOEXCEPT; | |||
+// expected-error@-1 {{replacement function 'operator delete[]' cannot be declared 'inline'}} | |||
#ifdef __cpp_sized_deal | #ifdef __cpp_sized_deal | ||
-inline void operator delete(void*, size_t) NOEXCEPT; | +inline void operator delete(void*, size_t) NOEXCEPT; | ||
-inline void operator delete[](void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} | +// expected-error@-1 {{replacement function 'operator delete' cannot be declared 'inline'}} | ||
+inline void operator delete[](void*, size_t) NOEXCEPT; | |||
+// expected-error@-1 {{replacement function 'operator delete[]' cannot be declared 'inline'}} | |||
#endif | #endif |
@@ -1,37 +1,53 @@ | |||
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s - | +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify=expected,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s - | +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s - | +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s - | +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2a %s - | +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2a %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
namespace dr705 { // dr705: yes | namespace dr705 { // dr705: yes | ||
namespace N { | namespace N { | ||
struct S {}; | struct S {}; | ||
- void f(S); // | + void f(S); // #dr705-f | ||
} | } | ||
void g() { | void g() { | ||
N::S s; | N::S s; | ||
f(s); // ok | f(s); // ok | ||
- (f)(s); | + (f)(s); | ||
+ // expected-error@-1 {{use of undeclared identifier 'f'}} | |||
+ // expected-note@#dr705-f {{'N::f' declared here}} | |||
} | } | ||
} | } | ||
namespace dr712 { // dr712: partial | namespace dr712 { // dr712: partial | ||
void use(int); | void use(int); | ||
void f() { | void f() { | ||
- const int a = 0; // | + const int a = 0; // #dr712-f-a | ||
struct X { | struct X { | ||
void g(bool cond) { | void g(bool cond) { | ||
use(a); | use(a); | ||
use((a)); | use((a)); | ||
use(cond ? a : a); | use(cond ? a : a); | ||
- use((cond, a)); // expected-warning 2{{left operand of comma operator has no effect}} FIXME: should only warn once | + // FIXME: should only warn once | ||
- | + use((cond, a)); | ||
- (void)a; // FIXME: expected-error {{declared in enclosing}} | + // expected-warning@-1 {{left operand of comma operator has no effect}} | ||
- (void)(a); // FIXME: expected-error {{declared in enclosing}} | + // expected-warning@-2 {{left operand of comma operator has no effect}} | ||
- (void)(cond ? a : a); // FIXME: expected-error 2{{declared in enclosing}} | + | ||
- (void)(cond, a); // FIXME: expected-error {{declared in enclosing}} expected-warning {{left operand of comma operator has no effect}} | + (void)a; | ||
+ // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME | |||
+ // expected-note@#dr712-f-a {{'a' declared here}} | |||
+ (void)(a); | |||
+ // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME | |||
+ // expected-note@#dr712-f-a {{'a' declared here}} | |||
+ (void)(cond ? a : a); // #dr712-ternary | |||
+ // expected-error@#dr712-ternary {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME | |||
+ // expected-note@#dr712-f-a {{'a' declared here}} | |||
+ // expected-error@#dr712-ternary {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME | |||
+ // expected-note@#dr712-f-a {{'a' declared here}} | |||
+ (void)(cond, a); // #dr712-comma | |||
+ // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME | |||
+ // expected-note@#dr712-f-a {{'a' declared here}} | |||
+ // expected-warning@#dr712-comma {{left operand of comma operator has no effect}} | |||
} | } | ||
}; | }; | ||
} | } | ||
@@ -39,14 +55,18 @@ namespace dr712 { // dr712: partial | |||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
void g() { | void g() { | ||
struct A { int n; }; | struct A { int n; }; | ||
- constexpr A a = {0}; | + constexpr A a = {0}; // #dr712-g-a | ||
struct X { | struct X { | ||
void g(bool cond) { | void g(bool cond) { | ||
use(a.n); | use(a.n); | ||
use(a.*&A::n); | use(a.*&A::n); | ||
- (void)a.n; | + (void)a.n; | ||
- (void)(a.*&A::n); // FIXME: expected-error {{declared in enclosing}} | + // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::g'}} FIXME | ||
+ // since-cxx11-note@#dr712-g-a {{'a' declared here}} | |||
+ (void)(a.*&A::n); | |||
+ // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::g'}} FIXME | |||
+ // since-cxx11-note@#dr712-g-a {{'a' declared here}} | |||
} | } | ||
}; | }; | ||
} | } | ||
@@ -55,9 +75,10 @@ namespace dr712 { // dr712: partial | |||
namespace dr727 { // dr727: partial | namespace dr727 { // dr727: partial | ||
struct A { | struct A { | ||
- template<typename T> struct C; // | + template<typename T> struct C; // #dr727-C | ||
- template<typename T> void f(); // | + template<typename T> void f(); // #dr727-f | ||
- template<typename T> static int N; // | + template<typename T> static int N; // #dr727-N | ||
+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}} | |||
template<> struct C<int>; | template<> struct C<int>; | ||
template<> void f<int>(); | template<> void f<int>(); | ||
@@ -67,19 +88,40 @@ namespace dr727 { // dr727: partial | |||
template<typename T> static int N<T*>; | template<typename T> static int N<T*>; | ||
struct B { | struct B { | ||
- template<> struct C<float>; | + template<> struct C<float>; | ||
- template<> void f<float>(); // expected-error {{no function template matches}} | + // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} | ||
- template<> static int N<float>; // expected-error {{not in class 'A' or an enclosing namespace}} | + // expected-note@#dr727-C {{explicitly specialized declaration is here}} | ||
- | + template<> void f<float>(); | ||
- | + // expected-error@-1 {{no function template matches function template specialization 'f'}} | ||
- template<typename T> static int N<T**>; // expected-error {{not in class 'A' or an enclosing namespace}} | + template<> static int N<float>; | ||
- | + // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} | ||
- template<> struct A::C<double>; // expected-error {{not in class 'A' or an enclosing namespace}} | + // expected-note@#dr727-N {{explicitly specialized declaration is here}} | ||
- template<> void A::f<double>(); // expected-error {{no function template matches}} expected-error {{cannot have a qualified name}} | + | ||
- template<> static int A::N<double>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}} | + template<typename T> struct C<T**>; | ||
- | + // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} | ||
- template<typename T> struct A::C<T***>; // expected-error {{not in class 'A' or an enclosing namespace}} | + // expected-note@#dr727-C {{explicitly specialized declaration is here}} | ||
- template<typename T> static int | + template<typename T> static int N<T**>; | ||
+ // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}} | |||
+ | |||
+ template<> struct A::C<double>; | |||
+ // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-C {{explicitly specialized declaration is here}} | |||
+ template<> void A::f<double>(); | |||
+ // expected-error@-1 {{o function template matches function template specialization 'f'}} | |||
+ // expected-error@-2 {{non-friend class member 'f' cannot have a qualified name}} | |||
+ template<> static int A::N<double>; | |||
+ // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} | |||
+ // expected-error@-2 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}} | |||
+ | |||
+ template<typename T> struct A::C<T***>; | |||
+ // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-C {{explicitly specialized declaration is here}} | |||
+ template<typename T> static int A::N<T***>; | |||
+ // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} | |||
+ // expected-error@-2 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}} | |||
}; | }; | ||
}; | }; | ||
@@ -91,19 +133,36 @@ namespace dr727 { // dr727: partial | |||
template<typename T> int A::N<T****>; | template<typename T> int A::N<T****>; | ||
namespace C { | namespace C { | ||
- template<> struct A::C<long>; | + template<> struct A::C<long>; | ||
- | + // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} | ||
- template<> int A::N<long>; // expected-error {{not in class 'A' or an enclosing namespace}} | + // expected-note@#dr727-C {{explicitly specialized declaration is here}} | ||
- | + template<> void A::f<long>(); | ||
- | + // expected-error@-1 {{function template specialization of 'f' not in class 'A' or an enclosing namespace}} | ||
- template<typename T> int A::N<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}} | + // expected-note@#dr727-f {{explicitly specialized declaration is here}} | ||
+ template<> int A::N<long>; | |||
+ // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}} | |||
+ | |||
+ template<typename T> struct A::C<T*****>; | |||
+ // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-C {{explicitly specialized declaration is here}} | |||
+ template<typename T> int A::N<T*****>; | |||
+ // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} | |||
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}} | |||
} | } | ||
template<typename> | template<typename> | ||
struct D { | struct D { | ||
- template<typename T> struct C { typename T::error e; }; | + template<typename T> struct C { typename T::error e; }; | ||
- template<typename T> void f() { T::error; } // expected-error {{no members}} | + // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} | ||
- template<typename T> static const int N = T::error; // expected-error {{no members}} expected-error 0-1{{C++14}} | + // expected-note@#dr727-C-float {{in instantiation of template class 'dr727::D<int>::C<float>' requested here}} | ||
+ template<typename T> void f() { T::error; } | |||
+ // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} | |||
+ // expected-note@#dr727-f-float {{in instantiation of function template specialization 'dr727::D<int>::f<float>' requested here}} | |||
+ template<typename T> static const int N = T::error; | |||
+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}} | |||
+ // expected-error@-2 {{type 'float' cannot be used prior to '::' because it has no members}} | |||
+ // expected-note@#dr727-N-float {{in instantiation of static data member 'dr727::D<int>::N<float>' requested here}} | |||
template<> struct C<int> {}; | template<> struct C<int> {}; | ||
template<> void f<int>() {} | template<> void f<int>() {} | ||
@@ -114,7 +173,8 @@ namespace dr727 { // dr727: partial | |||
template<typename> | template<typename> | ||
struct E { | struct E { | ||
- template<> void f<void>() {} | + template<> void f<void>() {} | ||
+ // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}} | |||
}; | }; | ||
}; | }; | ||
@@ -126,9 +186,9 @@ namespace dr727 { // dr727: partial | |||
D<int>::C<int*>(); | D<int>::C<int*>(); | ||
int b = D<int>::N<int*>; | int b = D<int>::N<int*>; | ||
- D<int>::C<float>(); // | + D<int>::C<float>(); // #dr727-C-float | ||
- di.f<float>(); // | + di.f<float>(); // #dr727-f-float | ||
- int c = D<int>::N<float>; // | + int c = D<int>::N<float>; // #dr727-N-float | ||
} | } | ||
namespace mixed_inner_oute | namespace mixed_inner_oute | ||
@@ -148,28 +208,30 @@ namespace dr727 { // dr727: partial | |||
#if __cplusplus >= 201402L | #if __cplusplus >= 201402L | ||
template<int> struct B { | template<int> struct B { | ||
template<int> static const int u = 1; | template<int> static const int u = 1; | ||
- template<> static const int u<0> = 2; // | + template<> static const int u<0> = 2; // #dr727-u0 | ||
// Note that in C++17 onwards, these are implicitly inline, and so the | // Note that in C++17 onwards, these are implicitly inline, and so the | ||
// initializer of v<0> is not instantiated with the declaration. In | // initializer of v<0> is not instantiated with the declaration. In | ||
// C++14, v<0> is a non-defining declaration and its initializer is | // C++14, v<0> is a non-defining declaration and its initializer is | ||
// instantiated with the class. | // instantiated with the class. | ||
template<int> static constexpr int v = 1; | template<int> static constexpr int v = 1; | ||
- template<> static constexpr int v<0> = 2; // #v0 | + template<> static constexpr int v<0> = 2; // #dr727-v0 | ||
- template<int> static const inline int w = 1; | + template<int> static const inline int w = 1; | ||
- template<> static const inline int w<0> = 2; // expected-error 0-1{{C++17 extension}} | + // cxx14-error@-1 {{inline variables are a C++17 extension}} | ||
+ template<> static const inline int w<0> = 2; | |||
+ // cxx14-error@-1 {{inline variables are a C++17 extension}} | |||
}; | }; | ||
template<> template<int> constexpr int B<0>::u = 3; | template<> template<int> constexpr int B<0>::u = 3; | ||
- template<> template<> constexpr int B<0>::u<0> = 4; | + template<> template<> constexpr int B<0>::u<0> = 4; | ||
+ // since-cxx14-error@-1 {{static data member 'u' already has an initializer}} | |||
+ // since-cxx14-note@#dr727-u0 {{previous initialization is here}} | |||
template<> template<int> constexpr int B<0>::v = 3; | template<> template<int> constexpr int B<0>::v = 3; | ||
template<> template<> constexpr int B<0>::v<0> = 4; | template<> template<> constexpr int B<0>::v<0> = 4; | ||
-#if __cplusplus < 201702L | + // cxx14-error@-1 {{static data member 'v' already has an initializer}} | ||
- // | + // cxx14-note@#dr727-v0 {{previous initialization is here}} | ||
- // expected-note@#v0 {{here}} | |||
-#endif | |||
template<> template<int> constexpr int B<0>::w = 3; | template<> template<int> constexpr int B<0>::w = 3; | ||
template<> template<> constexpr int B<0>::w<0> = 4; | template<> template<> constexpr int B<0>::w<0> = 4; | ||
@@ -182,10 +244,8 @@ namespace dr727 { // dr727: partial | |||
static_assert(B<1>().v<0> == 2, ""); | static_assert(B<1>().v<0> == 2, ""); | ||
static_assert(B<0>().v<1> == 3, ""); | static_assert(B<0>().v<1> == 3, ""); | ||
static_assert(B<0>().v<0> == 4, ""); | static_assert(B<0>().v<0> == 4, ""); | ||
-#if __cplusplus < 201702L | + // cxx14-error@-1 {{static assertion failed due to requirement 'dr727::mixed_inner_oute | ||
- // expected-error@-2 {{failed}} \ | + // cxx14-note@-2 {{expression evaluates to '2 == 4'}} | ||
- // expected-note@-2 {{evaluates to '2 == 4'}} | |||
-#endif | |||
static_assert(B<1>().w<1> == 1, ""); | static_assert(B<1>().w<1> == 1, ""); | ||
static_assert(B<1>().w<0> == 2, ""); | static_assert(B<1>().w<0> == 2, ""); | ||
@@ -205,13 +265,23 @@ namespace dr727 { // dr727: partial | |||
template<> int f2<T>() {} | template<> int f2<T>() {} | ||
template<> int f2<U>() {} | template<> int f2<U>() {} | ||
- template<typename> static int v1; | + template<typename> static int v1; | ||
- template<> static int v1<T>; // expected-note {{previous}} | + // cxx98-11-error@-1 {{variable templates are a C++14 extension}} | ||
- template<> static int | + template<> static int v1<T>; // #dr727-v1-T | ||
- | + template<> static int v1<U>; | ||
- template<typename> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}} | + // expected-error@-1 {{duplicate member 'v1'}} | ||
- template<> static inline int v2<T>; // expected-error 0-1{{C++17 extension}} expected-note {{previous}} | + // expected-note@#dr727-Collision-int-int {{in instantiation of template class 'dr727::Collision<int, int>' requested here}} | ||
- template<> static inline int v2<U>; // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}} | + // expected-note@#dr727-v1-T {{previous}} | ||
+ | |||
+ template<typename> static inline int v2; | |||
+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}} | |||
+ // cxx98-14-error@-2 {{inline variables are a C++17 extension}} | |||
+ template<> static inline int v2<T>; // #dr727-v2-T | |||
+ // cxx98-14-error@-1 {{inline variables are a C++17 extension}} | |||
+ template<> static inline int v2<U>; | |||
+ // cxx98-14-error@-1 {{inline variables are a C++17 extension}} | |||
+ // expected-error@-2 {{duplicate member 'v2'}} | |||
+ // expected-note@#dr727-v2-T {{previous declaration is here}} | |||
// FIXME: Missing diagnostic for duplicate class explicit specialization. | // FIXME: Missing diagnostic for duplicate class explicit specialization. | ||
template<typename> struct S1; | template<typename> struct S1; | ||
@@ -219,10 +289,12 @@ namespace dr727 { // dr727: partial | |||
template<> struct S1<U>; | template<> struct S1<U>; | ||
template<typename> struct S2; | template<typename> struct S2; | ||
- template<> struct S2<T> {}; // | + template<> struct S2<T> {}; // #dr727-S2-T | ||
- template<> struct S2<U> {}; | + template<> struct S2<U> {}; | ||
+ // expected-error@-1 {{redefinition of 'S2<int>'}} | |||
+ // expected-note@#dr727-S2-T {{previous}} | |||
}; | }; | ||
- Collision<int, int> c; // | + Collision<int, int> c; // #dr727-Collision-int-int | ||
} | } | ||
namespace dr777 { // dr777: 3.7 | namespace dr777 { // dr777: 3.7 |
@@ -1,30 +1,27 @@ | |||
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s - | +// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
+#if __cplusplus == 199711L | |||
// expected-no-diagnostics | // expected-no-diagnostics | ||
+#endif | |||
-namespace dr873 { // dr873: | +namespace dr873 { // dr873: 3.0 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
template <typename T> void f(T &&); | template <typename T> void f(T &&); | ||
-template <> void f(int &) | +template <> void f(int &) = delete; // #dr873-lvalue-ref | ||
-template <> void f(int &&) | +template <> void f(int &&) = delete; // #dr873-rvalue-ref | ||
void g(int i) { | void g(int i) { | ||
- f(i); // calls f<int&>(int&) | + f(i); // calls f<int&>(int&) | ||
-#pragma clang __debug dump f(i) | + // since-cxx11-error@-1 {{call to deleted function 'f'}} | ||
- // CHECK: CallExpr {{.*}} | + // since-cxx11-note@#dr873-lvalue-ref {{candidate function [with T = int &] has been implicitly deleted}} | ||
- // CHECK-NEXT: |-ImplicitCastExpr | + f(0); // calls f<int>(int&&) | ||
- // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'f' 'void (int &)' {{.*}} | + // since-cxx11-error@-1 {{call to deleted function 'f'}} | ||
- | + // since-cxx11-note@#dr873-rvalue-ref {{candidate function [with T = int] has been implicitly deleted}} | ||
- f(0); // calls f<int>(int&&), i.e., #2 | |||
-#pragma clang __debug dump f(0) | |||
- // CHECK: CallExpr {{.*}} | |||
- // CHECK-NEXT: |-ImplicitCastExpr | |||
- // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'f' 'void (int &&)' {{.*}} | |||
} | } | ||
#endif | #endif | ||
} // namespace dr873 | } // namespace dr873 |
@@ -1,9 +1,9 @@ | |||
-// RUN: %clang_cc1 -std=c++98 %s - | +// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++11 %s - | +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++14 %s - | +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++17 %s - | +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++20 %s - | +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
-// RUN: %clang_cc1 -std=c++23 %s - | +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors | ||
namespace std { | namespace std { | ||
__extension__ typedef __SIZE_TYPE__ size_t; | __extension__ typedef __SIZE_TYPE__ size_t; | ||
@@ -43,30 +43,34 @@ namespace dr948 { // dr948: 3.7 | |||
#endif | #endif | ||
} | } | ||
-namespace dr952 { // dr952: | +namespace dr952 { // dr952: 2.8 | ||
namespace example1 { | namespace example1 { | ||
struct A { | struct A { | ||
- typedef int I; // #dr952- | + typedef int I; // #dr952-I | ||
}; | }; | ||
-struct B : private A { // #dr952- | +struct B : private A { // #dr952-B | ||
}; | }; | ||
struct C : B { | struct C : B { | ||
void f() { | void f() { | ||
- I i1; // expected-error {{private member}} | + I i1; | ||
- // expected-note@#dr952-inheritance {{constrained by private inheritance}} | + // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}} | ||
- // | + // expected-note@#dr952-B {{constrained by private inheritance here}} | ||
+ // expected-note@#dr952-I {{member is declared here}} | |||
} | } | ||
- I i2; // expected-error {{private member}} | + I i2; | ||
- // expected-note@#dr952-inheritance {{constrained by private inheritance}} | + // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}} | ||
- // | + // expected-note@#dr952-B {{constrained by private inheritance here}} | ||
+ // expected-note@#dr952-I {{member is declared here}} | |||
struct D { | struct D { | ||
- I i3; // expected-error {{private member}} | + I i3; | ||
- // expected-note@#dr952-inheritance {{constrained by private inheritance}} | + // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}} | ||
- // | + // expected-note@#dr952-B {{constrained by private inheritance here}} | ||
+ // expected-note@#dr952-I {{member is declared here}} | |||
void g() { | void g() { | ||
- I i4; | + I i4; | ||
- // expected-note@#dr952-inheritance {{constrained by private inheritance}} | + // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}} | ||
- // | + // expected-note@#dr952-B {{constrained by private inheritance here}} | ||
+ // expected-note@#dr952-I {{member is declared here}} | |||
} | } | ||
}; | }; | ||
}; | }; | ||
@@ -91,10 +95,10 @@ namespace dr974 { // dr974: yes | |||
} | } | ||
namespace dr977 { // dr977: yes | namespace dr977 { // dr977: yes | ||
-enum E { e = E() }; | +enum E { e = E() }; // #dr977-E | ||
#if !defined(_WIN32) || defined(__MINGW32__) | #if !defined(_WIN32) || defined(__MINGW32__) | ||
-// expected-error@- | +// expected-error@#dr977-E {{invalid use of incomplete type 'E'}} | ||
-// | +// expected-note@#dr977-E {{definition of 'dr977::E' is not complete until the closing '}'}} | ||
#endif | #endif | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
enum E2 : int { e2 = E2() }; | enum E2 : int { e2 = E2() }; | ||
@@ -105,23 +109,29 @@ enum struct E4 : int { e = static_cast<int> | |||
namespace dr990 { // dr990: 3.5 | namespace dr990 { // dr990: 3.5 | ||
#if __cplusplus >= 201103L | #if __cplusplus >= 201103L | ||
- struct A { // | + struct A { // #dr990-A | ||
- A(std::initializer_list<int>); // | + A(std::initializer_list<int>); // #dr990-A-init-list | ||
}; | }; | ||
struct B { | struct B { | ||
A a; | A a; | ||
}; | }; | ||
B b1 { }; | B b1 { }; | ||
- B b2 { 1 }; | + B b2 { 1 }; | ||
+ // since-cxx11-error@-1 {{no viable conversion from 'int' to 'A'}} | |||
+ // since-cxx11-note@#dr990-A {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A &' for 1st argument}} | |||
+ // since-cxx11-note@#dr990-A {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A &&' for 1st argument}} | |||
+ // since-cxx11-note@#dr990-A-init-list {{candidate constructor not viable: no known conversion from 'int' to 'std::initializer_list | |||
B b3 { { 1 } }; | B b3 { { 1 } }; | ||
struct C { | struct C { | ||
C(); | C(); | ||
C(int); | C(int); | ||
- C(std::initializer_list<int>) = delete; // | + C(std::initializer_list<int>) = delete; // #dr990-deleted | ||
}; | }; | ||
C c1[3] { 1 }; // ok | C c1[3] { 1 }; // ok | ||
- C c2[3] { 1, {2} }; | + C c2[3] { 1, {2} }; | ||
+ // since-cxx11-error@-1 {{call to deleted constructor of 'C'}} | |||
+ // since-cxx11-note@#dr990-deleted {{'C' has been explicitly marked deleted here}} | |||
struct D { | struct D { | ||
D(); | D(); |
@@ -0,0 +1,47 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+ | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcomb | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcomb | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+ | |||
+#include <arm_sme_draft_sp | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin.§ | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+// CHECK-LABEL: @test_svreinterpr | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[CNT:%.*]]) | |||
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z31test_svreint | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[CNT:%.*]]) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+svbool_t test_svreinterpr | |||
+{ | |||
+ return SVE_ACLE_FUNC(svreinterpret,_b | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svreinterpr | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[PG:%.*]]) | |||
+// CHECK-NEXT: ret target("aarch64.svcount") [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z31test_svreint | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[PG:%.*]]) | |||
+// CPP-CHECK-NEXT: ret target("aarch64.svcount") [[TMP0]] | |||
+// | |||
+svcount_t test_svreinterpr | |||
+{ | |||
+ return SVE_ACLE_FUNC(svreinterpret,_c | |||
+} |
@@ -0,0 +1,343 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcomb | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcomb | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -target-feature +sme-f64f64 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+ | |||
+#include <arm_sme_draft_sp | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 | |||
+#endif | |||
+ | |||
+// SVQRSHR | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshr_u1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]] | |||
+// | |||
+svuint16_t test_svsqrshr_u1 | |||
+ return SVE_ACLE_FUNC(svqrshr,_n,_u16, | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshr_s1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]] | |||
+// | |||
+svint16_t test_svsqrshr_s1 | |||
+ return SVE_ACLE_FUNC(svqrshr,_n,_s16, | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshr_u8 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z23test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+svuint8_t test_svsqrshr_u8 | |||
+ return SVE_ACLE_FUNC(svqrshr,_n,_u8,_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshr_s8 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z23test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+svint8_t test_svsqrshr_s8 | |||
+ return SVE_ACLE_FUNC(svqrshr,_n,_s8,_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshr_u1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+svuint16_t test_svsqrshr_u1 | |||
+ return SVE_ACLE_FUNC(svqrshr,_n,_u16, | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshr_s1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+svint16_t test_svsqrshr_s1 | |||
+ return SVE_ACLE_FUNC(svqrshr,_n,_s16, | |||
+} | |||
+ | |||
+// SVQRSHRN | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshrn_u | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+svuint8_t test_svsqrshrn_u | |||
+ return SVE_ACLE_FUNC(svqrshrn,_n,_u8, | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshrn_s | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+svint8_t test_svsqrshrn_s | |||
+ return SVE_ACLE_FUNC(svqrshrn,_n,_s8, | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshrn_u | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z25test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+svuint16_t test_svsqrshrn_u | |||
+ return SVE_ACLE_FUNC(svqrshrn,_n,_u16 | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshrn_s | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z25test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+svint16_t test_svsqrshrn_s | |||
+ return SVE_ACLE_FUNC(svqrshrn,_n,_s16 | |||
+} | |||
+ | |||
+// SVSQRSHRU | |||
+ | |||
+// CHECK-LABEL: @test_svsvqrshru_ | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z26test_svsvqrs | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]] | |||
+// | |||
+svuint16_t test_svsvqrshru_ | |||
+ return SVE_ACLE_FUNC(svqrshru,_n,_u16 | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshru_u | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshru.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z24test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshru.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+svuint8_t test_svsqrshru_u | |||
+ return SVE_ACLE_FUNC(svqrshru,_n,_u8, | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshru_u | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z25test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+svuint16_t test_svsqrshru_u | |||
+ return SVE_ACLE_FUNC(svqrshru,_n,_u16 | |||
+} | |||
+ | |||
+// SQRSHRUN x 4 | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshrun_ | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrun.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 32) | |||
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z25test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrun.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 32) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]] | |||
+// | |||
+svuint8_t test_svsqrshrun_ | |||
+ return SVE_ACLE_FUNC(svqrshrun,_n,_u8 | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svsqrshrun_ | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrun.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 64) | |||
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z26test_svsqrsh | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6) | |||
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrun.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 64) | |||
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]] | |||
+// | |||
+svuint16_t test_svsqrshrun_ | |||
+ return SVE_ACLE_FUNC(svqrshrun,_n,_u1 | |||
+} |
@@ -0,0 +1,38 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+ | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+#include <arm_sve.h> | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+// CHECK-LABEL: @test_svcreate2_s | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16) | |||
+// CHECK-NEXT: ret <vscale x 32 x i1> [[TMP1]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z17test_svcreat | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 32 x i1> [[TMP1]] | |||
+// | |||
+svboolx2_t test_svcreate2_s | |||
+{ | |||
+ return SVE_ACLE_FUNC(svcreate2,_b8,,)(x0, x1); | |||
+} |
@@ -0,0 +1,42 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+ | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+#include <arm_sve.h> | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+// CHECK-LABEL: @test_svcreate4_b | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0) | |||
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16) | |||
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP1]], <vscale x 16 x i1> [[X2:%.*]], i64 32) | |||
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP2]], <vscale x 16 x i1> [[X4:%.*]], i64 48) | |||
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP3]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z17test_svcreat | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16) | |||
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP1]], <vscale x 16 x i1> [[X2:%.*]], i64 32) | |||
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP2]], <vscale x 16 x i1> [[X4:%.*]], i64 48) | |||
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP3]] | |||
+// | |||
+svboolx4_t test_svcreate4_b | |||
+{ | |||
+ return SVE_ACLE_FUNC(svcreate4,_b8,,)(x0, x1, x2, x4); | |||
+} |
@@ -0,0 +1,49 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+// REQUIRES: aarch64-registered-target | |||
+#include <arm_sve.h> | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+// CHECK-LABEL: @test_svget2_b8_0 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 0) | |||
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svget2_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+svbool_t test_svget2_b8_0 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svget2,_b8,,)(tuple, 0); | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svget2_b8_1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 16) | |||
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svget2_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+svbool_t test_svget2_b8_1 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svget2,_b8,,)(tuple, 1); | |||
+} |
@@ -0,0 +1,72 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+ | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+#include <arm_sve.h> | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+// NOTE: For these tests clang converts the struct parameter into | |||
+// several parameters, one for each member of the original struct. | |||
+// CHECK-LABEL: @test_svget4_b8_0 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 0) | |||
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svget4_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+svbool_t test_svget4_b8_0 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svget4,_b8,,)(tuple, 0); | |||
+} | |||
+ | |||
+// NOTE: For these tests clang converts the struct parameter into | |||
+// several parameters, one for each member of the original struct. | |||
+// CHECK-LABEL: @test_svget4_b8_1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 16) | |||
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svget4_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+svbool_t test_svget4_b8_1 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svget4,_b8,,)(tuple, 1); | |||
+} | |||
+ | |||
+// NOTE: For these tests clang converts the struct parameter into | |||
+// several parameters, one for each member of the original struct. | |||
+// CHECK-LABEL: @test_svget4_b8_3 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 48) | |||
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svget4_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 48) | |||
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]] | |||
+// | |||
+svbool_t test_svget4_b8_3 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svget4,_b8,,)(tuple, 3); | |||
+} |
@@ -0,0 +1,52 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+ | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+#include <arm_sve.h> | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+// CHECK-LABEL: @test_svset2_b8_0 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0) | |||
+// CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svset2_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]] | |||
+// | |||
+svboolx2_t test_svset2_b8_0 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svset2,_b8,,)(tuple, 0, x); | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svset2_b8_1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16) | |||
+// CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svset2_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]] | |||
+// | |||
+svboolx2_t test_svset2_b8_1 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svset2,_b8,,)(tuple, 1, x); | |||
+} | |||
+ |
@@ -0,0 +1,66 @@ | |||
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_c | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -DSVE_OVERLOADED_ | |||
+// RUN: | opt -S -passes=mem2reg,tailcall | |||
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s | |||
+// REQUIRES: aarch64-registered-target | |||
+ | |||
+#include <arm_sve.h> | |||
+ | |||
+#ifdef SVE_OVERLOADED_F | |||
+// A simple used,unused... macro, long enough to represent any SVE builtin. | |||
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3, | |||
+#else | |||
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 | |||
+#endif | |||
+ | |||
+ | |||
+// CHECK-LABEL: @test_svset4_b8_0 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0) | |||
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svset4_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0) | |||
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]] | |||
+// | |||
+svboolx4_t test_svset4_b8_0 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svset4,_b8,,)(tuple, 0, x); | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svset4_b8_1 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16) | |||
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svset4_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16) | |||
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]] | |||
+// | |||
+svboolx4_t test_svset4_b8_1 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svset4,_b8,,)(tuple, 1, x); | |||
+} | |||
+ | |||
+// CHECK-LABEL: @test_svset4_b8_3 | |||
+// CHECK-NEXT: entry: | |||
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 48) | |||
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]] | |||
+// | |||
+// CPP-CHECK-LABEL: @_Z16test_svset4_ | |||
+// CPP-CHECK-NEXT: entry: | |||
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 48) | |||
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]] | |||
+// | |||
+svboolx4_t test_svset4_b8_3 | |||
+{ | |||
+ return SVE_ACLE_FUNC(svset4,_b8,,)(tuple, 3, x); | |||
+} |
@@ -113,6 +113,9 @@ | |||
// RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m85 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV81M-CORTEX-M85-LINUX | // RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m85 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV81M-CORTEX-M85-LINUX | ||
// CHECK-ARMV81M-CORTEX-M85-LINUX: "target-features"="+armv8.1-m.main,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fullfp16,+hwdiv,+lob,+mve,+mve.fp,+pacbti,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp" | // CHECK-ARMV81M-CORTEX-M85-LINUX: "target-features"="+armv8.1-m.main,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fullfp16,+hwdiv,+lob,+mve,+mve.fp,+pacbti,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp" | ||
+// RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m52 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV81M-CORTEX-M52-LINUX | |||
+// CHECK-ARMV81M-CORTEX-M52-LINUX: "target-features"="+armv8.1-m.main,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fullfp16,+hwdiv,+lob,+mve,+mve.fp,+pacbti,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp" | |||
+ | |||
// RUN: %clang_cc1 -triple thumbv9.3a-linux-gnueabihf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARCH93 | // RUN: %clang_cc1 -triple thumbv9.3a-linux-gnueabihf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARCH93 | ||
// CHECK-ARCH93: "target-features"="+armv9.3-a,+thumb-mode,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8.7a,+v8.8a,+v9.1a,+v9.2a,+v9.3a,+v9a" | // CHECK-ARCH93: "target-features"="+armv9.3-a,+thumb-mode,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8.7a,+v8.8a,+v9.1a,+v9.2a,+v9.3a,+v9a" | ||
@@ -0,0 +1,331 @@ | |||
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa -ffreestanding \ | |||
+// RUN: -fvisibility=hidden | FileCheck %s | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi1a( | |||
+// CHECK: [[TMP0:%.*]] = load atomic i32, ptr [[PTR0:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = load atomic i32, ptr [[PTR1:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = load atomic i32, ptr [[PTR2:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = load atomic i32, ptr [[PTR3:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = load atomic i32, ptr [[PTR4:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+int fi1a(int *i) { | |||
+ int v; | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ return v; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi1b( | |||
+// CHECK: [[TMP0:%.*]] = load atomic i32, ptr [[PTR0:%.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = load atomic i32, ptr [[PTR1:%.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = load atomic i32, ptr [[PTR2:%.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = load atomic i32, ptr [[PTR3:%.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = load atomic i32, ptr [[PTR4:%.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// | |||
+int fi1b(int *i) { | |||
+ *i = __scoped_atomic_ | |||
+ *i = __scoped_atomic_ | |||
+ *i = __scoped_atomic_ | |||
+ *i = __scoped_atomic_ | |||
+ *i = __scoped_atomic_ | |||
+ return *i; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi2a( | |||
+// CHECK: store atomic i32 [[TMP0:%.+]], ptr [[PTR0:%.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP1:%.+]], ptr [[PTR1:%.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP2:%.+]], ptr [[PTR2:%.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP3:%.+]], ptr [[PTR3:%.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP4:%.+]], ptr [[PTR4:%.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// | |||
+void fi2a(int *i) { | |||
+ int v = 1; | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi2b( | |||
+// CHECK: store atomic i32 [[TMP0:%.+]], ptr [[PTR0:%.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP1:%.+]], ptr [[PTR1:%.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP2:%.+]], ptr [[PTR2:%.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP3:%.+]], ptr [[PTR3:%.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: store atomic i32 [[TMP4:%.+]], ptr [[PTR4:%.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+void fi2b(int *i) { | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi3a( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("one-as") monotonic, align 4 | |||
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("one-as") monotonic, align 4 | |||
+void fi3a(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi3b( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+void fi3b(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi3c( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+void fi3c(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi3d( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+void fi3d(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden void @fi3e( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+void fi3e(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi4a( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("one-as") acquire acquire, align 4 | |||
+_Bool fi4a(int *i) { | |||
+ int cmp = 0; | |||
+ int desired = 1; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_S | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi4b( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("agent-one-as") acquire acquire, align 4 | |||
+_Bool fi4b(int *i) { | |||
+ int cmp = 0; | |||
+ int desired = 1; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_D | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi4c( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("workgroup-one-as") acquire acquire, align 4 | |||
+_Bool fi4c(int *i) { | |||
+ int cmp = 0; | |||
+ int desired = 1; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_W | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi4d( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("wavefront-one-as") acquire acquire, align 4 | |||
+_Bool fi4d(int *i) { | |||
+ int cmp = 0; | |||
+ int desired = 1; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_W | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi4e( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("singlethread-one-as") acquire acquire, align 4 | |||
+_Bool fi4e(int *i) { | |||
+ int cmp = 0; | |||
+ int desired = 1; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_S | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi5a( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("one-as") acquire acquire, align 4 | |||
+_Bool fi5a(int *i) { | |||
+ int cmp = 0; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_S | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi5b( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("agent-one-as") acquire acquire, align 4 | |||
+_Bool fi5b(int *i) { | |||
+ int cmp = 0; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_D | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi5c( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("workgroup-one-as") acquire acquire, align 4 | |||
+_Bool fi5c(int *i) { | |||
+ int cmp = 0; | |||
+ return __scoped_atomic_ | |||
+ i, &cmp, 1, 1, __ATOMIC_ACQUIRE | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi5d( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("wavefront-one-as") acquire acquire, align 4 | |||
+_Bool fi5d(int *i) { | |||
+ int cmp = 0; | |||
+ return __scoped_atomic_ | |||
+ i, &cmp, 1, 1, __ATOMIC_ACQUIRE | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi5e( | |||
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("singlethread-one-as") acquire acquire, align 4 | |||
+_Bool fi5e(int *i) { | |||
+ int cmp = 0; | |||
+ return __scoped_atomic_ | |||
+ i, &cmp, 1, 1, __ATOMIC_ACQUIRE | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi6a( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("one-as") monotonic, align 4 | |||
+int fi6a(int *c, int *d) { | |||
+ int ret; | |||
+ __scoped_atomic_ | |||
+ return ret; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi6b( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("agent-one-as") monotonic, align 4 | |||
+int fi6b(int *c, int *d) { | |||
+ int ret; | |||
+ __scoped_atomic_ | |||
+ return ret; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi6c( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("workgroup-one-as") monotonic, align 4 | |||
+int fi6c(int *c, int *d) { | |||
+ int ret; | |||
+ __scoped_atomic_ | |||
+ return ret; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi6d( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("wavefront-one-as") monotonic, align 4 | |||
+int fi6d(int *c, int *d) { | |||
+ int ret; | |||
+ __scoped_atomic_ | |||
+ return ret; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden i32 @fi6e( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("singlethread-one-as") monotonic, align 4 | |||
+int fi6e(int *c, int *d) { | |||
+ int ret; | |||
+ __scoped_atomic_ | |||
+ return ret; | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi7a( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("one-as") monotonic, align 1 | |||
+_Bool fi7a(_Bool *c) { | |||
+ return __scoped_atomic_ | |||
+ __MEMORY_SCOPE_S | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi7b( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("agent-one-as") monotonic, align 1 | |||
+_Bool fi7b(_Bool *c) { | |||
+ return __scoped_atomic_ | |||
+ __MEMORY_SCOPE_D | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi7c( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("workgroup-one-as") monotonic, align 1 | |||
+_Bool fi7c(_Bool *c) { | |||
+ return __scoped_atomic_ | |||
+ __MEMORY_SCOPE_W | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi7d( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("wavefront-one-as") monotonic, align 1 | |||
+_Bool fi7d(_Bool *c) { | |||
+ return __scoped_atomic_ | |||
+ __MEMORY_SCOPE_W | |||
+} | |||
+ | |||
+// CHECK-LABEL: define hidden zeroext i1 @fi7e( | |||
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("singlethread-one-as") monotonic, align 1 | |||
+_Bool fi7e(_Bool *c) { | |||
+ return __scoped_atomic_ | |||
+ __MEMORY_SCOPE_S | |||
+} |
@@ -0,0 +1,116 @@ | |||
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s | |||
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH | |||
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA | |||
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA | |||
+// Test TBAA metadata generated by front-end. | |||
+// | |||
+// NO-TBAA-NOT: !tbaa | |||
+ | |||
+typedef unsigned char uint8_t; | |||
+typedef unsigned short uint16_t; | |||
+typedef unsigned int uint32_t; | |||
+typedef unsigned long long uint64_t; | |||
+ | |||
+typedef enum { | |||
+ RED_AUTO_32, | |||
+ GREEN_AUTO_32, | |||
+ BLUE_AUTO_32 | |||
+} EnumAuto32; | |||
+ | |||
+typedef enum { | |||
+ RED_AUTO_64, | |||
+ GREEN_AUTO_64, | |||
+ BLUE_AUTO_64 = 0x100000000ull | |||
+} EnumAuto64; | |||
+ | |||
+typedef enum : uint16_t { | |||
+ RED_16, | |||
+ GREEN_16, | |||
+ BLUE_16 | |||
+} Enum16; | |||
+ | |||
+typedef enum : uint8_t { | |||
+ RED_8, | |||
+ GREEN_8, | |||
+ BLUE_8 | |||
+} Enum8; | |||
+ | |||
+uint32_t g0(EnumAuto32 *E, uint32_t *val) { | |||
+// CHECK-LABEL: define{{.*}} i32 @g0( | |||
+// CHECK: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] | |||
+// CHECK: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | |||
+// CHECK: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | |||
+// PATH-LABEL: define{{.*}} i32 @g0( | |||
+// PATH: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] | |||
+// PATH: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | |||
+// PATH: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | |||
+ *val = 5; | |||
+ *E = RED_AUTO_32; | |||
+ return *val; | |||
+} | |||
+ | |||
+uint64_t g1(EnumAuto64 *E, uint64_t *val) { | |||
+// CHECK-LABEL: define{{.*}} i64 @g1( | |||
+// CHECK: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TAG_i64:!.*]] | |||
+// CHECK: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_long:!.*]] | |||
+// CHECK: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]] | |||
+// PATH-LABEL: define{{.*}} i64 @g1( | |||
+// PATH: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TAG_i64:!.*]] | |||
+// PATH: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_long:!.*]] | |||
+// PATH: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]] | |||
+ *val = 5; | |||
+ *E = RED_AUTO_64; | |||
+ return *val; | |||
+} | |||
+ | |||
+uint16_t g2(Enum16 *E, uint16_t *val) { | |||
+// CHECK-LABEL: define{{.*}} i16 @g2( | |||
+// CHECK: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]] | |||
+// CHECK: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | |||
+// CHECK: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | |||
+// PATH-LABEL: define{{.*}} i16 @g2( | |||
+// PATH: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]] | |||
+// PATH: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | |||
+// PATH: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | |||
+ *val = 5; | |||
+ *E = RED_16; | |||
+ return *val; | |||
+} | |||
+ | |||
+uint8_t g3(Enum8 *E, uint8_t *val) { | |||
+// CHECK-LABEL: define{{.*}} i8 @g3( | |||
+// CHECK: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TAG_i8:!.*]] | |||
+// CHECK: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | |||
+// CHECK: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | |||
+// PATH-LABEL: define{{.*}} i8 @g3( | |||
+// PATH: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TAG_i8:!.*]] | |||
+// PATH: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | |||
+// PATH: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | |||
+ *val = 5; | |||
+ *E = RED_8; | |||
+ return *val; | |||
+} | |||
+ | |||
+// CHECK: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]], | |||
+// CHECK: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"} | |||
+// CHECK: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0} | |||
+// CHECK: [[TYPE_i32]] = !{!"int", [[TYPE_char]], | |||
+// CHECK: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0} | |||
+// CHECK: [[TYPE_i64]] = !{!"long long", [[TYPE_char]], | |||
+// CHECK: [[TAG_long]] = !{[[TYPE_long:!.*]], [[TYPE_long]], i64 0} | |||
+// CHECK: [[TYPE_long]] = !{!"long", [[TYPE_char]], | |||
+// CHECK: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0} | |||
+// CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]], | |||
+// CHECK: [[TAG_i8]] = !{[[TYPE_i8:!.*]], [[TYPE_char]], i64 0} | |||
+ | |||
+// PATH: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]], | |||
+// PATH: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"} | |||
+// PATH: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0} | |||
+// PATH: [[TYPE_i32]] = !{!"int", [[TYPE_char]], | |||
+// PATH: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0} | |||
+// PATH: [[TYPE_i64]] = !{!"long long", [[TYPE_char]], | |||
+// PATH: [[TAG_long]] = !{[[TYPE_long:!.*]], [[TYPE_long]], i64 0} | |||
+// PATH: [[TYPE_long]] = !{!"long", [[TYPE_char]], | |||
+// PATH: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0} | |||
+// PATH: [[TYPE_i16]] = !{!"short", [[TYPE_char]], | |||
+// PATH: [[TAG_i8]] = !{[[TYPE_i8:!.*]], [[TYPE_char]], i64 0} |
@@ -17,31 +17,47 @@ | |||
//. | //. | ||
// CUDA: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | // CUDA: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | ||
// CUDA: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | // CUDA: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | ||
-// CUDA: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [ | +// CUDA: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00" | ||
-// CUDA: @.omp_offloading.entry. | +// CUDA: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z21__device_stub__kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 | ||
-// CUDA: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [ | +// CUDA: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00" | ||
-// CUDA: @.omp_offloading.entry. | +// CUDA: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 | ||
+// CUDA: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00" | |||
+// CUDA: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_en | |||
+// CUDA: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00" | |||
+// CUDA: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_en | |||
//. | //. | ||
// HIP: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | // HIP: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | ||
// HIP: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | // HIP: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | ||
-// HIP: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [ | +// HIP: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00" | ||
-// HIP: @.omp_offloading.entry. | +// HIP: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z6kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1 | ||
-// HIP: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [ | +// HIP: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00" | ||
-// HIP: @.omp_offloading.entry. | +// HIP: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries", align 1 | ||
+// HIP: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00" | |||
+// HIP: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_en | |||
+// HIP: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00" | |||
+// HIP: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_en | |||
//. | //. | ||
// CUDA-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | // CUDA-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | ||
// CUDA-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | // CUDA-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | ||
-// CUDA-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [ | +// CUDA-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00" | ||
-// CUDA-COFF: @.omp_offloading.entry. | +// CUDA-COFF: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z21__device_stub__kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 | ||
-// CUDA-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [ | +// CUDA-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00" | ||
-// CUDA-COFF: @.omp_offloading.entry. | +// CUDA-COFF: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 | ||
+// CUDA-COFF: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00" | |||
+// CUDA-COFF: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_en | |||
+// CUDA-COFF: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00" | |||
+// CUDA-COFF: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_en | |||
//. | //. | ||
// HIP-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | // HIP-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" | ||
// HIP-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | // HIP-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_en | ||
-// HIP-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [ | +// HIP-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00" | ||
-// HIP-COFF: @.omp_offloading.entry. | +// HIP-COFF: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z6kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1 | ||
-// HIP-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [ | +// HIP-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00" | ||
-// HIP-COFF: @.omp_offloading.entry. | +// HIP-COFF: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1 | ||
+// HIP-COFF: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00" | |||
+// HIP-COFF: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_en | |||
+// HIP-COFF: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00" | |||
+// HIP-COFF: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_en | |||
//. | //. | ||
// CUDA-LABEL: @_Z18__device_stu | // CUDA-LABEL: @_Z18__device_stu | ||
// CUDA-NEXT: entry: | // CUDA-NEXT: entry: | ||
@@ -72,34 +88,52 @@ | |||
// HIP-COFF-NEXT: ret void | // HIP-COFF-NEXT: ret void | ||
// | // | ||
__global__ void foo() {} | __global__ void foo() {} | ||
+__device__ int var = 1; | |||
+const __device__ int constant = 1; | |||
+extern __device__ int external; | |||
-// CUDA-LABEL: | +// CUDA-LABEL: @_Z21__device_stub__kernelv( | ||
// CUDA-NEXT: entry: | // CUDA-NEXT: entry: | ||
-// CUDA-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr | +// CUDA-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr @_Z21__device_stub__kernelv) | ||
// CUDA-NEXT: br label [[SETUP_END:%.*]] | // CUDA-NEXT: br label [[SETUP_END:%.*]] | ||
// CUDA: setup.end: | // CUDA: setup.end: | ||
// CUDA-NEXT: ret void | // CUDA-NEXT: ret void | ||
// | // | ||
-// HIP-LABEL: | +// HIP-LABEL: @_Z21__device_stub__kernelv( | ||
// HIP-NEXT: entry: | // HIP-NEXT: entry: | ||
-// HIP-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr | +// HIP-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr @_Z6kernelv) | ||
// HIP-NEXT: br label [[SETUP_END:%.*]] | // HIP-NEXT: br label [[SETUP_END:%.*]] | ||
// HIP: setup.end: | // HIP: setup.end: | ||
// HIP-NEXT: ret void | // HIP-NEXT: ret void | ||
// | // | ||
-// CUDA-COFF-LABEL: | +// CUDA-COFF-LABEL: @_Z21__device_stub__kernelv( | ||
// CUDA-COFF-NEXT: entry: | // CUDA-COFF-NEXT: entry: | ||
-// CUDA-COFF-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr | +// CUDA-COFF-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr @_Z21__device_stub__kernelv) | ||
// CUDA-COFF-NEXT: br label [[SETUP_END:%.*]] | // CUDA-COFF-NEXT: br label [[SETUP_END:%.*]] | ||
// CUDA-COFF: setup.end: | // CUDA-COFF: setup.end: | ||
// CUDA-COFF-NEXT: ret void | // CUDA-COFF-NEXT: ret void | ||
// | // | ||
-// HIP-COFF-LABEL: | +// HIP-COFF-LABEL: @_Z21__device_stub__kernelv( | ||
// HIP-COFF-NEXT: entry: | // HIP-COFF-NEXT: entry: | ||
-// HIP-COFF-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr | +// HIP-COFF-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr @_Z6kernelv) | ||
// HIP-COFF-NEXT: br label [[SETUP_END:%.*]] | // HIP-COFF-NEXT: br label [[SETUP_END:%.*]] | ||
// HIP-COFF: setup.end: | // HIP-COFF: setup.end: | ||
// HIP-COFF-NEXT: ret void | // HIP-COFF-NEXT: ret void | ||
// | // | ||
-__global__ void | +__global__ void kernel() { external = 1; } | ||
-__device__ int x = 1; | + | ||
+struct surfaceReference | |||
+ | |||
+template <typename T, int dim = 1> | |||
+struct __attribute__((device_builtin_s | |||
+ | |||
+surface<void> surf; | |||
+ | |||
+struct textureReference | |||
+ int desc; | |||
+}; | |||
+ | |||
+template <typename T, int dim = 1, int mode = 0> | |||
+struct __attribute__((device_builtin_t | |||
+ | |||
+texture<void> tex; |
@@ -1,7 +1,9 @@ | |||
// REQUIRES: aarch64-registered-target | // REQUIRES: aarch64-registered-target | ||
// RUN: %clang --target=aarch64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=ON | // RUN: %clang --target=aarch64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=ON | ||
+// RUN: %clang --target=aarch64_be -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=ON | |||
// ON: "-mllvm" "-enable-machine-outliner" | // ON: "-mllvm" "-enable-machine-outliner" | ||
// RUN: %clang --target=aarch64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF | // RUN: %clang --target=aarch64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF | ||
+// RUN: %clang --target=aarch64_be -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF | |||
// OFF: "-mllvm" "-enable-machine-outliner=never" | // OFF: "-mllvm" "-enable-machine-outliner=never" | ||
// RUN: %clang --target=x86_64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=WARN | // RUN: %clang --target=x86_64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=WARN | ||
// WARN: warning: 'x86_64' does not support '-moutline'; flag ignored [-Woption-ignored] | // WARN: warning: 'x86_64' does not support '-moutline'; flag ignored [-Woption-ignored] |
@@ -562,6 +562,9 @@ | |||
// RUN: %clang -target arm -mcpu=cortex-m85 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M85 %s | // RUN: %clang -target arm -mcpu=cortex-m85 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M85 %s | ||
// CHECK-CORTEX-M85: "-cc1"{{.*}} "-triple" "thumbv8.1m.main-{{.*}} "-target-cpu" "cortex-m85" | // CHECK-CORTEX-M85: "-cc1"{{.*}} "-triple" "thumbv8.1m.main-{{.*}} "-target-cpu" "cortex-m85" | ||
+// RUN: %clang -target arm -mcpu=cortex-m52 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M52 %s | |||
+// CHECK-CORTEX-M52: "-cc1"{{.*}} "-triple" "thumbv8.1m.main-{{.*}} "-target-cpu" "cortex-m52" | |||
+ | |||
// RUN: %clang -target arm -mcpu=neoverse-n2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEOVERSE-N2 %s | // RUN: %clang -target arm -mcpu=neoverse-n2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEOVERSE-N2 %s | ||
// CHECK-NEOVERSE-N2: "-cc1"{{.*}} "-triple" "armv8.5a-{{.*}}" "-target-cpu" "neoverse-n2" | // CHECK-NEOVERSE-N2: "-cc1"{{.*}} "-triple" "armv8.5a-{{.*}}" "-target-cpu" "neoverse-n2" | ||
@@ -55,14 +55,15 @@ | |||
// Check unbundling archive. | // Check unbundling archive. | ||
// | // | ||
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | ||
-// RUN: -input=%t.tgt1 -input=%t.tgt2 - | +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle1.bc -compress | ||
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | ||
-// RUN: -input=%t.tgt1 -input=%t.tgt2 - | +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle2.bc -compress | ||
-// RUN: llvm-ar cr %T/hip_archive.a %T/hip_bundle1.bc %T/hip_bundle2.bc | +// RUN: rm -f %t.hip_archive.a | ||
+// RUN: llvm-ar cr %t.hip_archive.a %t.hip_bundle1.bc %t.hip_bundle2.bc | |||
// RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | // RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | ||
-// RUN: - | +// RUN: -output=%t.hip_900.a -output=%t.hip_906.a -input=%t.hip_archive.a | ||
-// RUN: llvm-ar t | +// RUN: llvm-ar t %t.hip_900.a | FileCheck -check-prefix=HIP-AR-900 %s | ||
-// RUN: llvm-ar t | +// RUN: llvm-ar t %t.hip_906.a | FileCheck -check-prefix=HIP-AR-906 %s | ||
// HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900 | // HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900 | ||
// HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900 | // HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900 | ||
// HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 | // HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 |
@@ -48,18 +48,18 @@ | |||
// RUN: diff %t.tgt1 %t.res.tgt1 | // RUN: diff %t.tgt1 %t.res.tgt1 | ||
// RUN: diff %t.tgt2 %t.res.tgt2 | // RUN: diff %t.tgt2 %t.res.tgt2 | ||
-// | |||
// Check unbundling archive. | // Check unbundling archive. | ||
// | // | ||
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | ||
-// RUN: -input=%t.tgt1 -input=%t.tgt2 - | +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle1.bc -compress | ||
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | ||
-// RUN: -input=%t.tgt1 -input=%t.tgt2 - | +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle2.bc -compress | ||
-// RUN: llvm-ar cr %T/hip_archive.a %T/hip_bundle1.bc %T/hip_bundle2.bc | +// RUN: rm -f %t.hip_archive.a | ||
+// RUN: llvm-ar cr %t.hip_archive.a %t.hip_bundle1.bc %t.hip_bundle2.bc | |||
// RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | // RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ | ||
-// RUN: - | +// RUN: -output=%t.hip_900.a -output=%t.hip_906.a -input=%t.hip_archive.a | ||
-// RUN: llvm-ar t | +// RUN: llvm-ar t %t.hip_900.a | FileCheck -check-prefix=HIP-AR-900 %s | ||
-// RUN: llvm-ar t | +// RUN: llvm-ar t %t.hip_906.a | FileCheck -check-prefix=HIP-AR-906 %s | ||
// HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900 | // HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900 | ||
// HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900 | // HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900 | ||
// HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 | // HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 |
@@ -0,0 +1,250 @@ | |||
+// RUN: %clang -### --target=arm64-apple-darwin %s 2>&1 | FileCheck %s --check-prefix=DARWIN-DEFAULT | |||
+// DARWIN-DEFAULT-NOT: "-fdefine-target-os-macros" | |||
+ | |||
+// RUN: %clang -### --target=arm-none-linux-gnu %s 2>&1 | FileCheck %s --check-prefix=NON-DARWIN-DEFAULT | |||
+// RUN: %clang -### --target=x86_64-pc-win32 %s 2>&1 | FileCheck %s --check-prefix=NON-DARWIN-DEFAULT | |||
+// NON-DARWIN-DEFAULT-NOT: "-fdefine-target-os-macros" | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-macos \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=1 \ | |||
+// RUN: -DIPHONE=0 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-ios \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=1 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=1 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-ios-macabi \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=1 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=1 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-ios-simulator \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=1 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=1 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-tvos \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=1 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=1 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-tvos-simulator \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=1 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=1 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-watchos \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=1 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=1 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-watchos-simulator \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=1 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=1 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=1 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-driverkit \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=1 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=0 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=1 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=x86_64-pc-linux-gnu \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=0 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=0 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=1 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=x86_64-pc-win32 \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=0 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=0 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=1 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=x86_64-pc-windows-gnu \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=0 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=0 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=1 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=0 | |||
+ | |||
+// RUN: %clang -dM -E --target=sparc-none-solaris \ | |||
+// RUN: -fdefine-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s -DMAC=0 \ | |||
+// RUN: -DOSX=0 \ | |||
+// RUN: -DIPHONE=0 \ | |||
+// RUN: -DIOS=0 \ | |||
+// RUN: -DTV=0 \ | |||
+// RUN: -DWATCH=0 \ | |||
+// RUN: -DDRIVERKIT=0 \ | |||
+// RUN: -DMACCATALYST=0 \ | |||
+// RUN: -DEMBEDDED=0 \ | |||
+// RUN: -DSIMULATOR=0 \ | |||
+// RUN: -DWINDOWS=0 \ | |||
+// RUN: -DLINUX=0 \ | |||
+// RUN: -DUNIX=1 | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-macos \ | |||
+// RUN: -fno-define-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s --check-prefix=NEG | |||
+ | |||
+// RUN: %clang -dM -E --target=arm64-apple-macos \ | |||
+// RUN: -fdefine-target-os-macros \ | |||
+// RUN: -fno-define-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s --check-prefix=NEG | |||
+ | |||
+// RUN: %clang -dM -E --target=x86_64-pc-windows \ | |||
+// RUN: -fdefine-target-os-macros \ | |||
+// RUN: -fno-define-target-os-macros %s 2>&1 \ | |||
+// RUN: | FileCheck %s --check-prefix=NEG | |||
+ | |||
+// NEG-NOT: #define TARGET_OS_ | |||
+ | |||
+// CHECK-DAG: #define TARGET_OS_MAC [[MAC]] | |||
+// CHECK-DAG: #define TARGET_OS_OSX [[OSX]] | |||
+// CHECK-DAG: #define TARGET_OS_IPHONE | |||
+// CHECK-DAG: #define TARGET_OS_IOS [[IOS]] | |||
+// CHECK-DAG: #define TARGET_OS_TV [[TV]] | |||
+// CHECK-DAG: #define TARGET_OS_WATCH [[WATCH]] | |||
+// CHECK-DAG: #define TARGET_OS_DRIVER | |||
+// CHECK-DAG: #define TARGET_OS_MACCAT | |||
+// CHECK-DAG: #define TARGET_OS_SIMULA | |||
+// Deprecated | |||
+// CHECK-DAG: #define TARGET_OS_EMBEDD | |||
+// CHECK-DAG: #define TARGET_OS_NANO [[WATCH]] | |||
+// CHECK-DAG: #define TARGET_IPHONE_SI | |||
+// CHECK-DAG: #define TARGET_OS_UIKITF | |||
+// Non-darwin OSes | |||
+// CHECK-DAG: #define TARGET_OS_WIN32 [[WINDOWS]] | |||
+// CHECK-DAG: #define TARGET_OS_WINDOW | |||
+// CHECK-DAG: #define TARGET_OS_LINUX [[LINUX]] | |||
+// CHECK-DAG: #define TARGET_OS_UNIX [[UNIX]] |
@@ -4,13 +4,13 @@ | |||
// Test compress bundled bitcode. | // Test compress bundled bitcode. | ||
-// RUN: rm -rf | +// RUN: rm -rf %t.bc | ||
// RUN: %clang -c -v --target=x86_64-linux-gnu \ | // RUN: %clang -c -v --target=x86_64-linux-gnu \ | ||
// RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ | // RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ | ||
// RUN: -fgpu-rdc -nogpuinc -nogpulib \ | // RUN: -fgpu-rdc -nogpuinc -nogpulib \ | ||
// RUN: %S/Inputs/hip_multiple_inp | // RUN: %S/Inputs/hip_multiple_inp | ||
// RUN: --offload-compress --offload-device-only --gpu-bundle-output \ | // RUN: --offload-compress --offload-device-only --gpu-bundle-output \ | ||
-// RUN: -o | +// RUN: -o %t.bc \ | ||
// RUN: 2>&1 | FileCheck %s | // RUN: 2>&1 | FileCheck %s | ||
// CHECK: clang-offload-bundler{{.*}} -type=bc | // CHECK: clang-offload-bundler{{.*}} -type=bc | ||
@@ -23,7 +23,7 @@ | |||
// RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \ | // RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \ | ||
// RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \ | // RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \ | ||
// RUN: -fgpu-rdc -nogpulib \ | // RUN: -fgpu-rdc -nogpulib \ | ||
-// RUN: | +// RUN: %t.bc --offload-device-only \ | ||
// RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s | // RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s | ||
// UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc" | // UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc" |
@@ -4,13 +4,13 @@ | |||
// Test compress bundled bitcode. | // Test compress bundled bitcode. | ||
-// RUN: rm -rf | +// RUN: rm -rf %t.bc | ||
// RUN: %clang -c -v --target=x86_64-linux-gnu \ | // RUN: %clang -c -v --target=x86_64-linux-gnu \ | ||
// RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ | // RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ | ||
// RUN: -fgpu-rdc -nogpuinc -nogpulib \ | // RUN: -fgpu-rdc -nogpuinc -nogpulib \ | ||
// RUN: %S/Inputs/hip_multiple_inp | // RUN: %S/Inputs/hip_multiple_inp | ||
// RUN: --offload-compress --offload-device-only --gpu-bundle-output \ | // RUN: --offload-compress --offload-device-only --gpu-bundle-output \ | ||
-// RUN: -o | +// RUN: -o %t.bc \ | ||
// RUN: 2>&1 | FileCheck %s | // RUN: 2>&1 | FileCheck %s | ||
// CHECK: clang-offload-bundler{{.*}} -type=bc | // CHECK: clang-offload-bundler{{.*}} -type=bc | ||
@@ -23,7 +23,7 @@ | |||
// RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \ | // RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \ | ||
// RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \ | // RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \ | ||
// RUN: -fgpu-rdc -nogpulib \ | // RUN: -fgpu-rdc -nogpulib \ | ||
-// RUN: | +// RUN: %t.bc --offload-device-only \ | ||
// RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s | // RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s | ||
// UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc" | // UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc" |
@@ -80,24 +80,33 @@ | |||
// CUDA-NEXT: br i1 icmp ne (ptr @__start_cuda_off | // CUDA-NEXT: br i1 icmp ne (ptr @__start_cuda_off | ||
// CUDA: while.entry: | // CUDA: while.entry: | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %entry1 = phi ptr [ @__start_cuda_offloading_entries, %entry ], [ %11, %if.end ] | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %addr = load ptr, ptr %1, align 8 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %name = load ptr, ptr %2, align 8 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %size = load i64, ptr %3, align 4 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %flags = load i32, ptr %4, align 4 | ||
-// CUDA-NEXT: %5 = icmp eq i64 %size, 0 | +// CUDA-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_en | ||
-// CUDA-NEXT: br i1 %5, label %if.then, label %if.else | +// CUDA-NEXT: %textype = load i32, ptr %5, align 4 | ||
+// CUDA-NEXT: %type = and i32 %flags, 7 | |||
+// CUDA-NEXT: %6 = and i32 %flags, 8 | |||
+// CUDA-NEXT: %extern = lshr i32 %6, 3 | |||
+// CUDA-NEXT: %7 = and i32 %flags, 16 | |||
+// CUDA-NEXT: %constant = lshr i32 %7, 4 | |||
+// CUDA-NEXT: %8 = and i32 %flags, 32 | |||
+// CUDA-NEXT: %normalized = lshr i32 %8, 5 | |||
+// CUDA-NEXT: %9 = icmp eq i64 %size, 0 | |||
+// CUDA-NEXT: br i1 %9, label %if.then, label %if.else | |||
// CUDA: if.then: | // CUDA: if.then: | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %10 = call i32 @__cudaRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null) | ||
// CUDA-NEXT: br label %if.end | // CUDA-NEXT: br label %if.end | ||
// CUDA: if.else: | // CUDA: if.else: | ||
-// CUDA-NEXT: switch i32 | +// CUDA-NEXT: switch i32 %type, label %if.end [ | ||
// CUDA-NEXT: i32 0, label %sw.global | // CUDA-NEXT: i32 0, label %sw.global | ||
// CUDA-NEXT: i32 1, label %sw.managed | // CUDA-NEXT: i32 1, label %sw.managed | ||
// CUDA-NEXT: i32 2, label %sw.surface | // CUDA-NEXT: i32 2, label %sw.surface | ||
@@ -105,22 +114,24 @@ | |||
// CUDA-NEXT: ] | // CUDA-NEXT: ] | ||
// CUDA: sw.global: | // CUDA: sw.global: | ||
-// CUDA-NEXT: call void @__cudaRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 | +// CUDA-NEXT: call void @__cudaRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %extern, i64 %size, i32 %constant, i32 0) | ||
// CUDA-NEXT: br label %if.end | // CUDA-NEXT: br label %if.end | ||
// CUDA: sw.managed: | // CUDA: sw.managed: | ||
// CUDA-NEXT: br label %if.end | // CUDA-NEXT: br label %if.end | ||
// CUDA: sw.surface: | // CUDA: sw.surface: | ||
+// CUDA-NEXT: call void @__cudaRegisterSu | |||
// CUDA-NEXT: br label %if.end | // CUDA-NEXT: br label %if.end | ||
// CUDA: sw.texture: | // CUDA: sw.texture: | ||
+// CUDA-NEXT: call void @__cudaRegisterTe | |||
// CUDA-NEXT: br label %if.end | // CUDA-NEXT: br label %if.end | ||
// CUDA: if.end: | // CUDA: if.end: | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %11 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1 | ||
-// CUDA-NEXT: | +// CUDA-NEXT: %12 = icmp eq ptr %11, @__stop_cuda_offloading_entries | ||
-// CUDA-NEXT: br i1 | +// CUDA-NEXT: br i1 %12, label %while.end, label %while.entry | ||
// CUDA: while.end: | // CUDA: while.end: | ||
// CUDA-NEXT: ret void | // CUDA-NEXT: ret void | ||
@@ -168,7 +179,7 @@ | |||
// HIP-NEXT: br i1 icmp ne (ptr @__start_hip_offl | // HIP-NEXT: br i1 icmp ne (ptr @__start_hip_offl | ||
// HIP: while.entry: | // HIP: while.entry: | ||
-// HIP-NEXT: %entry1 = phi ptr [ @__start_hip_offloading_entries, %entry ], [ | +// HIP-NEXT: %entry1 = phi ptr [ @__start_hip_offloading_entries, %entry ], [ %11, %if.end ] | ||
// HIP-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_en | // HIP-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_en | ||
// HIP-NEXT: %addr = load ptr, ptr %1, align 8 | // HIP-NEXT: %addr = load ptr, ptr %1, align 8 | ||
// HIP-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_en | // HIP-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_en | ||
@@ -176,16 +187,25 @@ | |||
// HIP-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_en | // HIP-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_en | ||
// HIP-NEXT: %size = load i64, ptr %3, align 4 | // HIP-NEXT: %size = load i64, ptr %3, align 4 | ||
// HIP-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_en | // HIP-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_en | ||
-// HIP-NEXT: | +// HIP-NEXT: %flags = load i32, ptr %4, align 4 | ||
-// HIP-NEXT: %5 = icmp eq i64 %size, 0 | +// HIP-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_en | ||
-// HIP-NEXT: br i1 %5, label %if.then, label %if.else | +// HIP-NEXT: %textype = load i32, ptr %5, align 4 | ||
+// HIP-NEXT: %type = and i32 %flags, 7 | |||
+// HIP-NEXT: %6 = and i32 %flags, 8 | |||
+// HIP-NEXT: %extern = lshr i32 %6, 3 | |||
+// HIP-NEXT: %7 = and i32 %flags, 16 | |||
+// HIP-NEXT: %constant = lshr i32 %7, 4 | |||
+// HIP-NEXT: %8 = and i32 %flags, 32 | |||
+// HIP-NEXT: %normalized = lshr i32 %8, 5 | |||
+// HIP-NEXT: %9 = icmp eq i64 %size, 0 | |||
+// HIP-NEXT: br i1 %9, label %if.then, label %if.else | |||
// HIP: if.then: | // HIP: if.then: | ||
-// HIP-NEXT: | +// HIP-NEXT: %10 = call i32 @__hipRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null) | ||
// HIP-NEXT: br label %if.end | // HIP-NEXT: br label %if.end | ||
// HIP: if.else: | // HIP: if.else: | ||
-// HIP-NEXT: switch i32 | +// HIP-NEXT: switch i32 %type, label %if.end [ | ||
// HIP-NEXT: i32 0, label %sw.global | // HIP-NEXT: i32 0, label %sw.global | ||
// HIP-NEXT: i32 1, label %sw.managed | // HIP-NEXT: i32 1, label %sw.managed | ||
// HIP-NEXT: i32 2, label %sw.surface | // HIP-NEXT: i32 2, label %sw.surface | ||
@@ -193,22 +213,24 @@ | |||
// HIP-NEXT: ] | // HIP-NEXT: ] | ||
// HIP: sw.global: | // HIP: sw.global: | ||
-// HIP-NEXT: call void @__hipRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 | +// HIP-NEXT: call void @__hipRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %extern, i64 %size, i32 %constant, i32 0) | ||
// HIP-NEXT: br label %if.end | // HIP-NEXT: br label %if.end | ||
// HIP: sw.managed: | // HIP: sw.managed: | ||
// HIP-NEXT: br label %if.end | // HIP-NEXT: br label %if.end | ||
// HIP: sw.surface: | // HIP: sw.surface: | ||
+// HIP-NEXT: call void @__hipRegisterSur | |||
// HIP-NEXT: br label %if.end | // HIP-NEXT: br label %if.end | ||
// HIP: sw.texture: | // HIP: sw.texture: | ||
+// HIP-NEXT: call void @__hipRegisterTex | |||
// HIP-NEXT: br label %if.end | // HIP-NEXT: br label %if.end | ||
// HIP: if.end: | // HIP: if.end: | ||
-// HIP-NEXT: | +// HIP-NEXT: %11 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1 | ||
-// HIP-NEXT: | +// HIP-NEXT: %12 = icmp eq ptr %11, @__stop_hip_offloading_entries | ||
-// HIP-NEXT: br i1 | +// HIP-NEXT: br i1 %12, label %while.end, label %while.entry | ||
// HIP: while.end: | // HIP: while.end: | ||
// HIP-NEXT: ret void | // HIP-NEXT: ret void |
@@ -4,29 +4,42 @@ | |||
// RUN: %t/c.reference.output.json.in >> %t/c.reference.output.json | // RUN: %t/c.reference.output.json.in >> %t/c.reference.output.json | ||
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacemen | // RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacemen | ||
// RUN: %t/objc.reference.output.json.in >> %t/objc.reference.output.json | // RUN: %t/objc.reference.output.json.in >> %t/objc.reference.output.json | ||
+// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacemen | |||
+// RUN: %t/objcpp.reference.output.json.in >> %t/objcpp.reference.output.json | |||
-// RUN: | +// RUN: %clang_cc1 -extract-api -x c-header -triple arm64-apple-macosx \ | ||
// RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s | // RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s | ||
-// RUN: | +// RUN: %clang_cc1 -extract-api -x objective-c-header -triple arm64-apple-macosx \ | ||
// RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s | // RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s | ||
+// RUN: %clang_cc1 -extract-api -x objective-c++-header -triple arm64-apple-macosx \ | |||
+// RUN: %t/objcpp.h -o %t/objcpp.output.json | FileCheck -allow-empty %s | |||
// Generator version is not consistent across test runs, normalize it. | // Generator version is not consistent across test runs, normalize it. | ||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ | // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ | ||
// RUN: %t/c.output.json >> %t/c.output-normalized.json | // RUN: %t/c.output.json >> %t/c.output-normalized.json | ||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ | // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ | ||
// RUN: %t/objc.output.json >> %t/objc.output-normalized.json | // RUN: %t/objc.output.json >> %t/objc.output-normalized.json | ||
+// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ | |||
+// RUN: %t/objcpp.output.json >> %t/objcpp.output-normalized.json | |||
// RUN: diff %t/c.reference.output.json %t/c.output-normalized.json | // RUN: diff %t/c.reference.output.json %t/c.output-normalized.json | ||
// RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json | // RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json | ||
+// RUN: diff %t/objcpp.reference.output.json %t/objcpp.output-normalized.json | |||
// CHECK-NOT: error: | // CHECK-NOT: error: | ||
// CHECK-NOT: warning: | // CHECK-NOT: warning: | ||
//--- c.h | //--- c.h | ||
char c; | char c; | ||
+///expected-no-diagnostics | |||
//--- objc.h | //--- objc.h | ||
char objc; | char objc; | ||
+///expected-no-diagnostics | |||
+ | |||
+//--- objcpp.h | |||
+char objcpp; | |||
+///expected-no-diagnostics | |||
//--- c.reference.output.json.in | //--- c.reference.output.json.in | ||
{ | { | ||
@@ -196,3 +209,87 @@ char objc; | |||
} | } | ||
] | ] | ||
} | } | ||
+//--- objcpp.reference.output.json.in | |||
+{ | |||
+ "metadata": { | |||
+ "formatVersion": { | |||
+ "major": 0, | |||
+ "minor": 5, | |||
+ "patch": 3 | |||
+ }, | |||
+ "generator": "?" | |||
+ }, | |||
+ "module": { | |||
+ "name": "", | |||
+ "platform": { | |||
+ "architecture": "arm64", | |||
+ "operatingSystem": { | |||
+ "minimumVersion": { | |||
+ "major": 11, | |||
+ "minor": 0, | |||
+ "patch": 0 | |||
+ }, | |||
+ "name": "macosx" | |||
+ }, | |||
+ "vendor": "apple" | |||
+ } | |||
+ }, | |||
+ "relationships": [], | |||
+ "symbols": [ | |||
+ { | |||
+ "accessLevel": "public", | |||
+ "declarationFragm | |||
+ { | |||
+ "kind": "typeIdentifier", | |||
+ "preciseIdentifie | |||
+ "spelling": "char" | |||
+ }, | |||
+ { | |||
+ "kind": "text", | |||
+ "spelling": " " | |||
+ }, | |||
+ { | |||
+ "kind": "identifier", | |||
+ "spelling": "objcpp" | |||
+ }, | |||
+ { | |||
+ "kind": "text", | |||
+ "spelling": ";" | |||
+ } | |||
+ ], | |||
+ "identifier": { | |||
+ "interfaceLanguag | |||
+ "precise": "c:@objcpp" | |||
+ }, | |||
+ "kind": { | |||
+ "displayName": "Global Variable", | |||
+ "identifier": "objective-c++.var" | |||
+ }, | |||
+ "location": { | |||
+ "position": { | |||
+ "character": 5, | |||
+ "line": 0 | |||
+ }, | |||
+ "uri": "file://INPUT_DIR/objcpp.h" | |||
+ }, | |||
+ "names": { | |||
+ "navigator": [ | |||
+ { | |||
+ "kind": "identifier", | |||
+ "spelling": "objcpp" | |||
+ } | |||
+ ], | |||
+ "subHeading": [ | |||
+ { | |||
+ "kind": "identifier", | |||
+ "spelling": "objcpp" | |||
+ } | |||
+ ], | |||
+ "title": "objcpp" | |||
+ }, | |||
+ "pathComponents": [ | |||
+ "objcpp" | |||
+ ] | |||
+ } | |||
+ ] | |||
+} |
@@ -1,7 +1,7 @@ | |||
// Use CHECK-NEXT instead of multiple CHECK-SAME to ensure we will fail if there is anything extra in the output. | // Use CHECK-NEXT instead of multiple CHECK-SAME to ensure we will fail if there is anything extra in the output. | ||
// RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix ARM | // RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix ARM | ||
// ARM: error: unknown target CPU 'not-a-cpu' | // ARM: error: unknown target CPU 'not-a-cpu' | ||
-// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}} | +// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-m52, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}} | ||
// RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64 | // RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64 | ||
// AARCH64: error: unknown target CPU 'not-a-cpu' | // AARCH64: error: unknown target CPU 'not-a-cpu' |
@@ -144,7 +144,13 @@ int main() { | |||
// CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 | // CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 | ||
// CHECK: [[A_ADDR2:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 0 | // CHECK: [[A_ADDR2:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 0 | ||
// CHECK: [[P4:%.+]] = mul nuw i64 [[CONV:%.+]], 4 | // CHECK: [[P4:%.+]] = mul nuw i64 [[CONV:%.+]], 4 | ||
-// CHECK: [[ | +// CHECK: [[A_ADDR3:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 0 | ||
+// CHECK: [[L5:%.+]] = load i32, ptr [[A_ADDR3]] | |||
+// CHECK: [[L6:%.+]] = sext i32 [[L5]] to i64 | |||
+// CHECK: [[LB_ADD_LEN:%lb_add_len]] = add nsw i64 -1, [[L6]] | |||
+// CHECK: [[ARR_ADDR9:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 3 | |||
+// CHECK: [[ARR_IDX10:%arrayidx.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR9]], i64 0, i64 %lb_add_len | |||
+// CHECK: [[ARR_END:%.+]] = getelementptr i32, ptr [[ARR_IDX10]], i32 1 | |||
// CHECK: [[E:%.+]] = ptrtoint ptr [[ARR_END]] to i64 | // CHECK: [[E:%.+]] = ptrtoint ptr [[ARR_END]] to i64 | ||
// CHECK: [[B:%.+]] = ptrtoint ptr [[A_ADDR]] to i64 | // CHECK: [[B:%.+]] = ptrtoint ptr [[A_ADDR]] to i64 | ||
// CHECK: [[DIFF:%.+]] = sub i64 [[E]], [[B]] | // CHECK: [[DIFF:%.+]] = sub i64 [[E]], [[B]] |
@@ -7,6 +7,17 @@ void func() { | |||
#pragma acc | #pragma acc | ||
for(;;){} | for(;;){} | ||
+ // expected-error@+4{{expected OpenACC directive}} | |||
+ // expected-error@+3{{expected clause-list or newline in OpenACC directive}} | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+#pragma acc(whatever) routine | |||
+ | |||
+ // expected-error@+3{{expected OpenACC directive}} | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+#pragma acc) routine | |||
+ | |||
// expected-error@+2{{invalid OpenACC directive 'invalid'}} | // expected-error@+2{{invalid OpenACC directive 'invalid'}} | ||
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | ||
#pragma acc invalid | #pragma acc invalid |
@@ -0,0 +1,157 @@ | |||
+// RUN: %clang_cc1 %s -verify -fopenacc | |||
+ | |||
+void func() { | |||
+ int i, j; | |||
+ | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait | |||
+ | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait ( | |||
+ | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait () | |||
+ | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait () clause-list | |||
+ | |||
+ // expected-error@+4{{expected expression}} | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: | |||
+ | |||
+ // expected-error@+2{{expected expression}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum:) | |||
+ | |||
+ // expected-error@+3{{expected expression}} | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum:) clause-list | |||
+ | |||
+ // expected-error@+4{{expected ':'}} | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: i + j | |||
+ | |||
+ // expected-error@+2{{expected ':'}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: i + j) | |||
+ | |||
+ // expected-error@+3{{expected ':'}} | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: i + j) clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (queues: | |||
+ | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (queues:) | |||
+ | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (queues:) clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: i + j:queues: | |||
+ | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: i + j:queues:) | |||
+ | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (devnum: i + j:queues:) clause-list | |||
+ | |||
+ // expected-error@+4{{use of undeclared identifier 'devnum'}} | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (queues:devnum: i + j | |||
+ | |||
+ // expected-error@+2{{use of undeclared identifier 'devnum'}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (queues:devnum: i + j) | |||
+ | |||
+ // expected-error@+3{{use of undeclared identifier 'devnum'}} | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait (queues:devnum: i + j) clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(i, j, 1+1, 3.3 | |||
+ | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(i, j, 1+1, 3.3) | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(i, j, 1+1, 3.3) clause-list | |||
+ | |||
+ // expected-error@+4{{expected expression}} | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(, | |||
+ | |||
+ // expected-error@+2{{expected expression}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(,) | |||
+ | |||
+ // expected-error@+3{{expected expression}} | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(,) clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(queues:i, j, 1+1, 3.3 | |||
+ | |||
+ // expected-error@+4{{expected expression}} | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(queues:i, j, 1+1, 3.3, | |||
+ | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(queues:i, j, 1+1, 3.3) | |||
+ | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(queues:i, j, 1+1, 3.3) clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3 | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3) | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3) clause-list | |||
+ | |||
+ // expected-error@+3{{expected ')'}} | |||
+ // expected-note@+2{{to match this '('}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3 | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) | |||
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}} | |||
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} | |||
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) clause-list | |||
+} |
@@ -217,6 +217,11 @@ | |||
// AARCH64-NEXT: #define __LONG_MAX__ 9223372036854775 | // AARCH64-NEXT: #define __LONG_MAX__ 9223372036854775 | ||
// AARCH64-NEXT: #define __LONG_WIDTH__ 64 | // AARCH64-NEXT: #define __LONG_WIDTH__ 64 | ||
// AARCH64-NEXT: #define __LP64__ 1 | // AARCH64-NEXT: #define __LP64__ 1 | ||
+// AARCH64-NEXT: #define __MEMORY_SCOPE_D | |||
+// AARCH64-NEXT: #define __MEMORY_SCOPE_S | |||
+// AARCH64-NEXT: #define __MEMORY_SCOPE_S | |||
+// AARCH64-NEXT: #define __MEMORY_SCOPE_W | |||
+// AARCH64-NEXT: #define __MEMORY_SCOPE_W | |||
// AARCH64-NEXT: #define __NO_INLINE__ 1 | // AARCH64-NEXT: #define __NO_INLINE__ 1 | ||
// AARCH64-NEXT: #define __NO_MATH_ERRNO_ | // AARCH64-NEXT: #define __NO_MATH_ERRNO_ | ||
// AARCH64-NEXT: #define __OBJC_BOOL_IS_B | // AARCH64-NEXT: #define __OBJC_BOOL_IS_B |
@@ -177,6 +177,11 @@ | |||
// LA32: #define __LONG_LONG_MAX_ | // LA32: #define __LONG_LONG_MAX_ | ||
// LA32: #define __LONG_MAX__ 2147483647L | // LA32: #define __LONG_MAX__ 2147483647L | ||
// LA32: #define __LONG_WIDTH__ 32 | // LA32: #define __LONG_WIDTH__ 32 | ||
+// LA32: #define __MEMORY_SCOPE_D | |||
+// LA32: #define __MEMORY_SCOPE_S | |||
+// LA32: #define __MEMORY_SCOPE_S | |||
+// LA32: #define __MEMORY_SCOPE_W | |||
+// LA32: #define __MEMORY_SCOPE_W | |||
// LA32: #define __NO_INLINE__ 1 | // LA32: #define __NO_INLINE__ 1 | ||
// LA32: #define __NO_MATH_ERRNO_ | // LA32: #define __NO_MATH_ERRNO_ | ||
// LA32: #define __OBJC_BOOL_IS_B | // LA32: #define __OBJC_BOOL_IS_B | ||
@@ -494,6 +499,11 @@ | |||
// LA64: #define __LONG_MAX__ 9223372036854775 | // LA64: #define __LONG_MAX__ 9223372036854775 | ||
// LA64: #define __LONG_WIDTH__ 64 | // LA64: #define __LONG_WIDTH__ 64 | ||
// LA64: #define __LP64__ 1 | // LA64: #define __LP64__ 1 | ||
+// LA64: #define __MEMORY_SCOPE_D | |||
+// LA64: #define __MEMORY_SCOPE_S | |||
+// LA64: #define __MEMORY_SCOPE_S | |||
+// LA64: #define __MEMORY_SCOPE_W | |||
+// LA64: #define __MEMORY_SCOPE_W | |||
// LA64: #define __NO_INLINE__ 1 | // LA64: #define __NO_INLINE__ 1 | ||
// LA64: #define __NO_MATH_ERRNO_ | // LA64: #define __NO_MATH_ERRNO_ | ||
// LA64: #define __OBJC_BOOL_IS_B | // LA64: #define __OBJC_BOOL_IS_B |
@@ -1742,6 +1742,11 @@ | |||
// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775 | // WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775 | ||
// WEBASSEMBLY64-NEXT:#define __LONG_WIDTH__ 64 | // WEBASSEMBLY64-NEXT:#define __LONG_WIDTH__ 64 | ||
// WEBASSEMBLY64-NEXT:#define __LP64__ 1 | // WEBASSEMBLY64-NEXT:#define __LP64__ 1 | ||
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_D | |||
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_S | |||
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_S | |||
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_W | |||
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_W | |||
// WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1 | // WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1 | ||
// WEBASSEMBLY-NEXT:#define __NO_MATH_ERRNO_ | // WEBASSEMBLY-NEXT:#define __NO_MATH_ERRNO_ | ||
// WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_B | // WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_B | ||
@@ -2057,6 +2062,11 @@ | |||
// AVR:#define __LDBL_MIN__ 1.17549435e-38L | // AVR:#define __LDBL_MIN__ 1.17549435e-38L | ||
// AVR:#define __LONG_LONG_MAX_ | // AVR:#define __LONG_LONG_MAX_ | ||
// AVR:#define __LONG_MAX__ 2147483647L | // AVR:#define __LONG_MAX__ 2147483647L | ||
+// AVR:#define __MEMORY_SCOPE_D | |||
+// AVR:#define __MEMORY_SCOPE_S | |||
+// AVR:#define __MEMORY_SCOPE_S | |||
+// AVR:#define __MEMORY_SCOPE_W | |||
+// AVR:#define __MEMORY_SCOPE_W | |||
// AVR:#define __NO_INLINE__ 1 | // AVR:#define __NO_INLINE__ 1 | ||
// AVR:#define __ORDER_BIG_ENDI | // AVR:#define __ORDER_BIG_ENDI | ||
// AVR:#define __ORDER_LITTLE_E | // AVR:#define __ORDER_LITTLE_E | ||
@@ -2348,6 +2358,11 @@ | |||
// RISCV32: #define __LITTLE_ENDIAN_ | // RISCV32: #define __LITTLE_ENDIAN_ | ||
// RISCV32: #define __LONG_LONG_MAX_ | // RISCV32: #define __LONG_LONG_MAX_ | ||
// RISCV32: #define __LONG_MAX__ 2147483647L | // RISCV32: #define __LONG_MAX__ 2147483647L | ||
+// RISCV32: #define __MEMORY_SCOPE_D | |||
+// RISCV32: #define __MEMORY_SCOPE_S | |||
+// RISCV32: #define __MEMORY_SCOPE_S | |||
+// RISCV32: #define __MEMORY_SCOPE_W | |||
+// RISCV32: #define __MEMORY_SCOPE_W | |||
// RISCV32: #define __NO_INLINE__ 1 | // RISCV32: #define __NO_INLINE__ 1 | ||
// RISCV32: #define __POINTER_WIDTH_ | // RISCV32: #define __POINTER_WIDTH_ | ||
// RISCV32: #define __PRAGMA_REDEFIN | // RISCV32: #define __PRAGMA_REDEFIN | ||
@@ -2555,6 +2570,11 @@ | |||
// RISCV64: #define __LONG_LONG_MAX_ | // RISCV64: #define __LONG_LONG_MAX_ | ||
// RISCV64: #define __LONG_MAX__ 9223372036854775 | // RISCV64: #define __LONG_MAX__ 9223372036854775 | ||
// RISCV64: #define __LP64__ 1 | // RISCV64: #define __LP64__ 1 | ||
+// RISCV64: #define __MEMORY_SCOPE_D | |||
+// RISCV64: #define __MEMORY_SCOPE_S | |||
+// RISCV64: #define __MEMORY_SCOPE_S | |||
+// RISCV64: #define __MEMORY_SCOPE_W | |||
+// RISCV64: #define __MEMORY_SCOPE_W | |||
// RISCV64: #define __NO_INLINE__ 1 | // RISCV64: #define __NO_INLINE__ 1 | ||
// RISCV64: #define __POINTER_WIDTH_ | // RISCV64: #define __POINTER_WIDTH_ | ||
// RISCV64: #define __PRAGMA_REDEFIN | // RISCV64: #define __PRAGMA_REDEFIN |
@@ -167,3 +167,21 @@ void test_svpmov_lane | |||
zn_u32 = svpmov_lane_u32_ | zn_u32 = svpmov_lane_u32_ | ||
zn_u64 = svpmov_lane_u64_ | zn_u64 = svpmov_lane_u64_ | ||
} | } | ||
+ | |||
+__attribute__((target("+sve2p1"))) | |||
+void test_svget_svset | |||
+ svset2(tuple2, -1, res); // expected-error {{argument value 1844674407370955 | |||
+ svset2(tuple2, 2, res); // expected-error {{argument value 2 is outside the valid range [0, 1]}} | |||
+ svset4(tuple4, -1, res); // expected-error {{argument value 1844674407370955 | |||
+ svset4(tuple4, 4, res); // expected-error {{argument value 4 is outside the valid range [0, 3]}} | |||
+ | |||
+ svget2(tuple2, -1); // expected-error {{argument value 1844674407370955 | |||
+ svget2(tuple2, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} | |||
+ svget4(tuple4, -1); // expected-error {{argument value 1844674407370955 | |||
+ svget4(tuple4, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} | |||
+ | |||
+ svset2(tuple2, idx, res); // expected-error {{argument to 'svste2' must be a constant integer}} | |||
+ svset4(tupl4, idx, res); // expected-error {{argument to 'svset4' must be a constant integer}} | |||
+ svget2(tuple2, idx); // expected-error {{argument to 'svget2' must be a constant integer}} | |||
+ svget4(tuple4, idx); // expected-error {{argument to 'svget4' must be a constant integer}} | |||
+} |
@@ -1,4 +1,5 @@ | |||
// RUN: %clang_cc1 -fsyntax-only -verify %s | // RUN: %clang_cc1 -fsyntax-only -verify %s | ||
+// RUN: %clang_cc1 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s | |||
__attribute__((noreturn)) extern void bar(); | __attribute__((noreturn)) extern void bar(); | ||
@@ -0,0 +1,101 @@ | |||
+// RUN: %clang_cc1 -x c -triple=amdgcn-amd-amdhsa -verify -fsyntax-only %s | |||
+// RUN: %clang_cc1 -x c -triple=x86_64-pc-linux-gnu -verify -fsyntax-only %s | |||
+ | |||
+int fi1a(int *i) { | |||
+ int v; | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ return v; | |||
+} | |||
+ | |||
+int fi1b(int *i) { | |||
+ *i = __scoped_atomic_ | |||
+ *i = __scoped_atomic_ | |||
+ *i = __scoped_atomic_ | |||
+ return *i; | |||
+} | |||
+ | |||
+int fi2a(int *i) { | |||
+ int v; | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ return v; | |||
+} | |||
+ | |||
+void fi2b(int *i) { | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+ __scoped_atomic_ | |||
+} | |||
+ | |||
+void fi3a(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+void fi3b(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+void fi3c(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+void fi3d(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) { | |||
+ *a = __scoped_atomic_ | |||
+ *b = __scoped_atomic_ | |||
+ *c = __scoped_atomic_ | |||
+ *d = __scoped_atomic_ | |||
+ *e = __scoped_atomic_ | |||
+ *f = __scoped_atomic_ | |||
+ *g = __scoped_atomic_ | |||
+ *h = __scoped_atomic_ | |||
+} | |||
+ | |||
+int fi4a(int *i) { | |||
+ int cmp = 0; | |||
+ int desired = 1; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_S | |||
+} | |||
+ | |||
+int fi5a(int *i) { | |||
+ int cmp = 0; | |||
+ return __scoped_atomic_ | |||
+ __ATOMIC_ACQUIRE | |||
+ __MEMORY_SCOPE_S | |||
+} | |||
+ | |||
+int fi6a(int *c, int *d) { | |||
+ int ret; | |||
+ __scoped_atomic_ | |||
+ return ret; | |||
+} | |||
+ | |||
+int fi7a(_Bool *c) { | |||
+ return __scoped_atomic_ | |||
+ __MEMORY_SCOPE_S | |||
+} |
@@ -0,0 +1,17 @@ | |||
+// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-default %s | |||
+ | |||
+int f1(int a) { | |||
+ switch (a) { // expected-warning {{'switch' missing 'default' label}} | |||
+ case 1: a++; break; | |||
+ case 2: a += 2; break; | |||
+ } | |||
+ return a; | |||
+} | |||
+ | |||
+int f2(int a) { | |||
+ switch (a) { // no-warning | |||
+ default: | |||
+ ; | |||
+ } | |||
+ return a; | |||
+} |
@@ -1,4 +1,4 @@ | |||
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused | +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused -Wno-c++23-lambda-attributes | ||
#include "Inputs/std-coroutine.h" | #include "Inputs/std-coroutine.h" | ||
@@ -64,14 +64,8 @@ Co<int> bar_coro(const int &b, int c) { | |||
: bar_coro(0, 1); // expected-warning {{returning address of local temporary object}} | : bar_coro(0, 1); // expected-warning {{returning address of local temporary object}} | ||
} | } | ||
-#define CORO_WRAPPER \ | |||
- _Pragma("clang diagnostic push") \ | |||
- _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \ | |||
- [[clang::coro_wrapper]] \ | |||
- _Pragma("clang diagnostic pop") | |||
- | |||
void lambdas() { | void lambdas() { | ||
- auto unsafe_lambda = [] | + auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) { | ||
return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}} | return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}} | ||
}; | }; | ||
auto coro_lambda = [] (const int&) -> Co<int> { | auto coro_lambda = [] (const int&) -> Co<int> { |
@@ -1,4 +1,4 @@ | |||
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra | +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-c++23-lambda-attributes | ||
#include "Inputs/std-coroutine.h" | #include "Inputs/std-coroutine.h" | ||
using std::suspend_always; | using std::suspend_always; | ||
@@ -45,11 +45,6 @@ Co<int> non_marked_wrapp | |||
} // namespace using_decl | } // namespace using_decl | ||
namespace lambdas { | namespace lambdas { | ||
-#define CORO_WRAPPER \ | |||
- _Pragma("clang diagnostic push") \ | |||
- _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \ | |||
- [[clang::coro_wrapper]] \ | |||
- _Pragma("clang diagnostic pop") | |||
void foo() { | void foo() { | ||
auto coro_lambda = []() -> Gen<int> { | auto coro_lambda = []() -> Gen<int> { | ||
@@ -59,7 +54,7 @@ void foo() { | |||
auto not_allowed_wrap | auto not_allowed_wrap | ||
return foo_coro(1); | return foo_coro(1); | ||
}; | }; | ||
- auto allowed_wrapper = [] | + auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen<int> { | ||
return foo_coro(1); | return foo_coro(1); | ||
}; | }; | ||
} | } |
@@ -171,3 +171,30 @@ namespace CtorTemplateBeat | |||
Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}} | Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}} | ||
Foo g(Derived d) { return Foo(d); } // ok, calls constructor | Foo g(Derived d) { return Foo(d); } // ok, calls constructor | ||
} | } | ||
+ | |||
+// Make sure we don't consider conversion functions for guaranteed copy elision | |||
+namespace GH39319 { | |||
+struct A { | |||
+ A(); | |||
+ A(const A&) = delete; // expected-note {{'A' has been explicitly marked deleted here}} | |||
+}; | |||
+struct B { | |||
+ operator A(); | |||
+} C; | |||
+A::A() : A(C) {} // expected-error {{call to deleted constructor of}} | |||
+ | |||
+struct A2 { | |||
+ struct B2 { | |||
+ operator A2(); | |||
+ }; | |||
+ A2() : A2(B2()) {} // expected-error {{call to deleted constructor of}} | |||
+ A2(const A2&) = delete; // expected-note {{'A2' has been explicitly marked deleted here}} | |||
+}; | |||
+ | |||
+template<typename A3> | |||
+class B3 : A3 { | |||
+ template<bool = C3<B3>()> // expected-warning 2{{use of function template name with no prior declaration in function call with explicit}} | |||
+ B3(); | |||
+}; B3(); // expected-error {{deduction guide declaration without trailing return type}} \ | |||
+ // expected-note {{while building implicit deduction guide first needed here}} | |||
+} |
@@ -1702,6 +1702,8 @@ struct TestScopedLockab | |||
bool getBool(); | bool getBool(); | ||
+ bool lock2Bool(MutexLock); | |||
+ | |||
void foo1() { | void foo1() { | ||
MutexLock mulock(&mu1); | MutexLock mulock(&mu1); | ||
a = 5; | a = 5; | ||
@@ -1718,6 +1720,12 @@ struct TestScopedLockab | |||
MutexLock{&mu1}, a = 5; | MutexLock{&mu1}, a = 5; | ||
} | } | ||
+ void temporary_cfg(int x) { | |||
+ // test the case where a pair of temporary Ctor and Dtor is in different CFG blocks | |||
+ lock2Bool(MutexLock{&mu1}) || x; | |||
+ MutexLock{&mu1}; // no-warn | |||
+ } | |||
+ | |||
void lifetime_extensi | void lifetime_extensi | ||
const MutexLock &mulock = MutexLock(&mu1); | const MutexLock &mulock = MutexLock(&mu1); | ||
a = 5; | a = 5; |
@@ -5,6 +5,14 @@ typedef vector<float, 3> float3; | |||
RWBuffer<float3> Buffer; | RWBuffer<float3> Buffer; | ||
+// expected-error@+2 {{class template 'RWBuffer' requires template arguments}} | |||
+// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}} | |||
+RWBuffer BufferErr1; | |||
+ | |||
+// expected-error@+2 {{too few template arguments for class template 'RWBuffer'}} | |||
+// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}} | |||
+RWBuffer<> BufferErr2; | |||
+ | |||
[numthreads(1,1,1)] | [numthreads(1,1,1)] | ||
void main() { | void main() { | ||
(void)Buffer.h; // expected-error {{'h' is a private member of 'hlsl::RWBuffer<float __attribute__((ext_vector_type(3)))>'}} | (void)Buffer.h; // expected-error {{'h' is a private member of 'hlsl::RWBuffer<float __attribute__((ext_vector_type(3)))>'}} |
@@ -0,0 +1,34 @@ | |||
+// RUN: %clang_cc1 -std=c++20 -verify %s | |||
[diff truncated] |